ruby_smb 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/ruby_smb/client.rb +26 -4
  5. data/lib/ruby_smb/client/authentication.rb +43 -25
  6. data/lib/ruby_smb/client/echo.rb +20 -2
  7. data/lib/ruby_smb/client/negotiation.rb +27 -12
  8. data/lib/ruby_smb/client/tree_connect.rb +20 -14
  9. data/lib/ruby_smb/error.rb +40 -1
  10. data/lib/ruby_smb/generic_packet.rb +33 -4
  11. data/lib/ruby_smb/smb1/dcerpc.rb +7 -2
  12. data/lib/ruby_smb/smb1/file.rb +60 -11
  13. data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
  14. data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
  15. data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
  16. data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
  17. data/lib/ruby_smb/smb1/packet/empty_packet.rb +7 -0
  18. data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
  19. data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
  20. data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
  21. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
  22. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
  23. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
  24. data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
  25. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
  26. data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
  27. data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
  28. data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
  29. data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
  30. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
  31. data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
  32. data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +2 -1
  33. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
  34. data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -1
  35. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
  36. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
  37. data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
  38. data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
  39. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
  40. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
  41. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
  42. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
  43. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
  44. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
  45. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
  46. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
  47. data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
  48. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
  49. data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
  50. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
  51. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
  52. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
  53. data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
  54. data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
  55. data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
  56. data/lib/ruby_smb/smb1/packet/write_andx_request.rb +2 -5
  57. data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
  58. data/lib/ruby_smb/smb1/pipe.rb +8 -3
  59. data/lib/ruby_smb/smb1/tree.rb +40 -2
  60. data/lib/ruby_smb/smb2/dcerpc.rb +7 -2
  61. data/lib/ruby_smb/smb2/file.rb +97 -1
  62. data/lib/ruby_smb/smb2/packet/close_request.rb +2 -4
  63. data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
  64. data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
  65. data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
  66. data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
  67. data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
  68. data/lib/ruby_smb/smb2/packet/error_packet.rb +7 -0
  69. data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
  70. data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
  71. data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
  72. data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
  73. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +2 -5
  74. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +2 -1
  75. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
  76. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
  77. data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
  78. data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
  79. data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
  80. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
  81. data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
  82. data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
  83. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +2 -5
  84. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +8 -2
  85. data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
  86. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
  87. data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
  88. data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
  89. data/lib/ruby_smb/smb2/pipe.rb +9 -9
  90. data/lib/ruby_smb/smb2/tree.rb +44 -6
  91. data/lib/ruby_smb/version.rb +1 -1
  92. data/spec/lib/ruby_smb/client_spec.rb +123 -11
  93. data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
  94. data/spec/lib/ruby_smb/smb1/file_spec.rb +182 -1
  95. data/spec/lib/ruby_smb/smb1/packet/{error_packet_spec.rb → empty_packet_spec.rb} +21 -0
  96. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +11 -2
  97. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
  98. data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
  99. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +63 -2
  100. data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
  101. data/spec/lib/ruby_smb/smb2/file_spec.rb +295 -2
  102. data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +51 -0
  103. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +8 -0
  104. data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +8 -0
  105. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +69 -3
  106. data/spec/lib/ruby_smb/smb2/tree_spec.rb +214 -0
  107. metadata +6 -4
  108. metadata.gz.sig +0 -0
@@ -48,6 +48,13 @@ RSpec.describe RubySMB::SMB2::Tree do
48
48
  tree.disconnect!
49
49
  end
50
50
 
51
+ it 'raises an InvalidPacket exception if the response is not valid' do
52
+ allow(client).to receive(:send_recv)
53
+ allow(RubySMB::SMB2::Packet::TreeDisconnectResponse).to receive(:read).and_return(disco_resp)
54
+ allow(disco_resp).to receive(:valid?).and_return(false)
55
+ expect { tree.disconnect! }.to raise_error(RubySMB::Error::InvalidPacket)
56
+ end
57
+
51
58
  it 'returns the NTStatus code from the response' do
52
59
  allow(client).to receive(:send_recv).and_return(disco_resp.to_binary_s)
53
60
  expect(tree.disconnect!).to eq disco_resp.status_code
@@ -129,6 +136,15 @@ RSpec.describe RubySMB::SMB2::Tree do
129
136
  expect(client).to receive(:send_recv).with(create_req).and_return(create_response.to_binary_s)
130
137
  tree.open_directory
131
138
  end
139
+
140
+ context 'when the response is not a valid packet' do
141
+ it 'raises an InvalidPacket exception' do
142
+ allow(client).to receive(:send_recv)
143
+ allow(RubySMB::SMB2::Packet::CreateResponse).to receive(:read).and_return(create_response)
144
+ create_response.smb2_header.command = RubySMB::SMB2::Commands::LOGOFF
145
+ expect { tree.open_directory }.to raise_error(RubySMB::Error::InvalidPacket)
146
+ end
147
+ end
132
148
  end
133
149
 
134
150
  describe '#list' do
@@ -202,6 +218,13 @@ RSpec.describe RubySMB::SMB2::Tree do
202
218
  expect(tree.list).to eq([file1])
203
219
  end
204
220
 
221
+ context 'when the response is not a valid packet' do
222
+ it 'raises an InvalidPacket exception' do
223
+ query_dir_res.smb2_header.command = RubySMB::SMB2::Commands::LOGOFF
224
+ expect { tree.list }.to raise_error(RubySMB::Error::InvalidPacket)
225
+ end
226
+ end
227
+
205
228
  context 'when multiple requests are needed to retrieve the full directory list' do
206
229
  before :example do
207
230
  query_dir_res.smb2_header.nt_status = WindowsError::NTStatus::STATUS_SUCCESS.value
@@ -238,4 +261,195 @@ RSpec.describe RubySMB::SMB2::Tree do
238
261
  end
239
262
 
240
263
  end
264
+
265
+ describe '#open_file' do
266
+ let(:create_request) { RubySMB::SMB2::Packet::CreateRequest.new }
267
+ let(:create_response) { RubySMB::SMB2::Packet::CreateResponse.new }
268
+ let(:filename) { "test_file\x00".encode('UTF-16LE') }
269
+
270
+ before :each do
271
+ allow(RubySMB::SMB2::Packet::CreateRequest).to receive(:new).and_return(create_request)
272
+ allow(RubySMB::SMB2::Packet::CreateResponse).to receive(:read).and_return(create_response)
273
+ end
274
+
275
+ it 'calls #set_header_fields' do
276
+ allow(client).to receive(:send_recv).and_return(create_response.to_binary_s)
277
+ expect(tree).to receive(:set_header_fields).with(create_request).and_call_original
278
+ tree.open_file(filename: filename)
279
+ end
280
+
281
+ describe 'filename' do
282
+ it 'takes the filename as an argument' do
283
+ allow(client).to receive(:send_recv) do |packet|
284
+ expect(packet.name).to eq(filename)
285
+ create_response.to_binary_s
286
+ end
287
+ tree.open_file(filename: filename)
288
+ end
289
+ end
290
+
291
+ describe 'attributes' do
292
+ it 'has the correct default fields set' do
293
+ allow(client).to receive(:send_recv) do |packet|
294
+ expect(packet.file_attributes.directory).to eq(0)
295
+ expect(packet.file_attributes.normal).to eq(1)
296
+ create_response.to_binary_s
297
+ end
298
+ tree.open_file(filename: filename)
299
+ end
300
+
301
+ it 'can take the Attributes as an argument' do
302
+ attributes = { normal: 0 }
303
+ allow(client).to receive(:send_recv) do |packet|
304
+ expect(packet.file_attributes.normal).to eq(0)
305
+ create_response.to_binary_s
306
+ end
307
+ tree.open_file(filename: filename, attributes: attributes)
308
+ end
309
+ end
310
+
311
+ describe 'options' do
312
+ it 'has the correct default fields set' do
313
+ allow(client).to receive(:send_recv) do |packet|
314
+ expect(packet.create_options.directory_file).to eq(0)
315
+ expect(packet.create_options.non_directory_file).to eq(1)
316
+ create_response.to_binary_s
317
+ end
318
+ tree.open_file(filename: filename)
319
+ end
320
+
321
+ it 'can take the Create Options as an argument' do
322
+ options = RubySMB::SMB1::BitField::CreateOptions.new(directory_file: 1)
323
+ allow(client).to receive(:send_recv) do |packet|
324
+ expect(packet.create_options.directory_file).to eq(1)
325
+ expect(packet.create_options.non_directory_file).to eq(0)
326
+ create_response.to_binary_s
327
+ end
328
+ tree.open_file(filename: filename, options: options)
329
+ end
330
+ end
331
+
332
+ describe 'disposition' do
333
+ it 'defaults to FILE_OPEN' do
334
+ allow(client).to receive(:send_recv) do |packet|
335
+ expect(packet.create_disposition).to eq(RubySMB::Dispositions::FILE_OPEN)
336
+ create_response.to_binary_s
337
+ end
338
+ tree.open_file(filename: filename)
339
+ end
340
+
341
+ it 'can take the Disposition as an argument' do
342
+ allow(client).to receive(:send_recv) do |packet|
343
+ expect(packet.create_disposition).to eq(RubySMB::Dispositions::FILE_OPEN_IF)
344
+ create_response.to_binary_s
345
+ end
346
+ tree.open_file(filename: filename, disposition: RubySMB::Dispositions::FILE_OPEN_IF)
347
+ end
348
+ end
349
+
350
+ describe 'impersonation level' do
351
+ it 'defaults to SEC_IMPERSONATE' do
352
+ allow(client).to receive(:send_recv) do |packet|
353
+ expect(packet.impersonation_level).to eq(RubySMB::ImpersonationLevels::SEC_IMPERSONATE)
354
+ create_response.to_binary_s
355
+ end
356
+ tree.open_file(filename: filename)
357
+ end
358
+
359
+ it 'can take the Impersonation Level as an argument' do
360
+ allow(client).to receive(:send_recv) do |packet|
361
+ expect(packet.impersonation_level).to eq(RubySMB::ImpersonationLevels::SEC_DELEGATE)
362
+ create_response.to_binary_s
363
+ end
364
+ tree.open_file(filename: filename, impersonation: RubySMB::ImpersonationLevels::SEC_DELEGATE)
365
+ end
366
+ end
367
+
368
+ describe 'RWD access permissions' do
369
+ it 'will set the read permission from the parameters' do
370
+ allow(client).to receive(:send_recv) do |packet|
371
+ expect(packet.share_access.read_access).to eq(1)
372
+ expect(packet.desired_access.read_data).to eq(1)
373
+ create_response.to_binary_s
374
+ end
375
+ tree.open_file(filename: filename, read: true)
376
+ end
377
+
378
+ it 'will set the write permission from the parameters' do
379
+ allow(client).to receive(:send_recv) do |packet|
380
+ expect(packet.share_access.write_access).to eq(1)
381
+ expect(packet.desired_access.write_data).to eq(1)
382
+ expect(packet.desired_access.append_data).to eq(1)
383
+ create_response.to_binary_s
384
+ end
385
+ tree.open_file(filename: filename, write: true)
386
+ end
387
+
388
+ it 'will set the delete permission from the parameters' do
389
+ allow(client).to receive(:send_recv) do |packet|
390
+ expect(packet.share_access.delete_access).to eq(1)
391
+ expect(packet.desired_access.delete_access).to eq(1)
392
+ create_response.to_binary_s
393
+ end
394
+ tree.open_file(filename: filename, delete: true)
395
+ end
396
+ end
397
+
398
+ it 'sets #requested_oplock to 0xFF' do
399
+ allow(client).to receive(:send_recv) do |packet|
400
+ expect(packet.requested_oplock).to eq(0xFF)
401
+ create_response.to_binary_s
402
+ end
403
+ tree.open_file(filename: filename, delete: true)
404
+ end
405
+
406
+ it 'sends the CreateRequest request packet and gets the expected CreateResponse response back' do
407
+ expect(client).to receive(:send_recv).with(create_request).and_return(create_response.to_binary_s)
408
+ tree.open_file(filename: filename)
409
+ end
410
+
411
+ context 'when sending the request packet and gets a response back' do
412
+ before :example do
413
+ allow(client).to receive(:send_recv).with(create_request).and_return(create_response.to_binary_s)
414
+ end
415
+
416
+ context 'when it is a file' do
417
+ it 'returns the expected RubySMB::SMB2::File object' do
418
+ file_obj = RubySMB::SMB2::File.new(name: filename, tree: tree, response: create_response)
419
+ expect(RubySMB::SMB2::File).to receive(:new).with(name: filename, tree: tree, response: create_response).and_return(file_obj)
420
+ expect(tree.open_file(filename: filename)).to eq(file_obj)
421
+ end
422
+ end
423
+
424
+ context 'when it is a pipe' do
425
+ it 'returns the expected RubySMB::SMB2::Pipe object' do
426
+ response.share_type = 0x02
427
+ pipe_obj = RubySMB::SMB2::Pipe.new(name: filename, tree: tree, response: create_response)
428
+ expect(RubySMB::SMB2::Pipe).to receive(:new).with(name: filename, tree: tree, response: create_response).and_return(pipe_obj)
429
+ expect(tree.open_file(filename: filename)).to eq(pipe_obj)
430
+ end
431
+ end
432
+
433
+ context 'when it is an unsupported share type' do
434
+ it 'raises a RubySMBError exception' do
435
+ response.share_type = 0x03
436
+ expect { tree.open_file(filename: filename) }.to raise_error(RubySMB::Error::RubySMBError)
437
+ end
438
+ end
439
+
440
+ context 'when the response is not a CreateResponse packet' do
441
+ it 'raises an InvalidPacket exception' do
442
+ create_response.smb2_header.command = RubySMB::SMB2::Commands::LOGOFF
443
+ expect { tree.open_file(filename: filename) }.to raise_error(RubySMB::Error::InvalidPacket)
444
+ end
445
+ end
446
+
447
+ context 'when the response status code is not STATUS_SUCCESS' do
448
+ it 'raises an UnexpectedStatusCode exception' do
449
+ create_response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_INVALID_HANDLE.value
450
+ expect { tree.open_file(filename: filename) }.to raise_error(RubySMB::Error::UnexpectedStatusCode)
451
+ end
452
+ end
453
+ end
454
+ end
241
455
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_smb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Maloney
@@ -91,7 +91,7 @@ cert_chain:
91
91
  G+Hmcg1v810agasPdoydE0RTVZgEOOMoQ07qu7JFXVWZ9ZQpHT7qJATWL/b2csFG
92
92
  8mVuTXnyJOKRJA==
93
93
  -----END CERTIFICATE-----
94
- date: 2018-07-03 00:00:00.000000000 Z
94
+ date: 2018-09-12 00:00:00.000000000 Z
95
95
  dependencies:
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: redcarpet
@@ -503,7 +503,7 @@ files:
503
503
  - spec/lib/ruby_smb/smb1/packet/close_response_spec.rb
504
504
  - spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb
505
505
  - spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb
506
- - spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb
506
+ - spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb
507
507
  - spec/lib/ruby_smb/smb1/packet/logoff_request_spec.rb
508
508
  - spec/lib/ruby_smb/smb1/packet/logoff_response_spec.rb
509
509
  - spec/lib/ruby_smb/smb1/packet/negotiate_request_spec.rb
@@ -566,6 +566,7 @@ files:
566
566
  - spec/lib/ruby_smb/smb2/packet/create_response_spec.rb
567
567
  - spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb
568
568
  - spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb
569
+ - spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb
569
570
  - spec/lib/ruby_smb/smb2/packet/ioctl_request_spec.rb
570
571
  - spec/lib/ruby_smb/smb2/packet/logoff_request_spec.rb
571
572
  - spec/lib/ruby_smb/smb2/packet/logoff_response_spec.rb
@@ -682,7 +683,7 @@ test_files:
682
683
  - spec/lib/ruby_smb/smb1/packet/close_response_spec.rb
683
684
  - spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb
684
685
  - spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb
685
- - spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb
686
+ - spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb
686
687
  - spec/lib/ruby_smb/smb1/packet/logoff_request_spec.rb
687
688
  - spec/lib/ruby_smb/smb1/packet/logoff_response_spec.rb
688
689
  - spec/lib/ruby_smb/smb1/packet/negotiate_request_spec.rb
@@ -745,6 +746,7 @@ test_files:
745
746
  - spec/lib/ruby_smb/smb2/packet/create_response_spec.rb
746
747
  - spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb
747
748
  - spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb
749
+ - spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb
748
750
  - spec/lib/ruby_smb/smb2/packet/ioctl_request_spec.rb
749
751
  - spec/lib/ruby_smb/smb2/packet/logoff_request_spec.rb
750
752
  - spec/lib/ruby_smb/smb2/packet/logoff_response_spec.rb
metadata.gz.sig CHANGED
Binary file