ruby_smb 2.0.3 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6cce717ed3175b8027db1e414fae576e984ff4c88a158568014b4c4eb06406f7
4
- data.tar.gz: fb9223d4f15a3ed99aca553523dd957ceb3173cef87b4ba3d29a409ae4baffda
3
+ metadata.gz: 43f9f98936e870ad767348eb90c66f17eaf5e56c62b7792e13502c860bf8c4f1
4
+ data.tar.gz: b57d0bdee72f2fde7ee700771f85cd0f442f3ca5be70b4564b1598df05474860
5
5
  SHA512:
6
- metadata.gz: 94319bee008719b00933ab82140fafd65c13344858f6677ecb26502cf22d087de0200c0feab9304959ac38df17fcac6540707e2b55457d8d92370484fbfbcd06
7
- data.tar.gz: bf55746b294b17d9a4633e1344d976bfdc13df89e96c1ea5861c55999fdd0e1367d25b0e7e1ec455d4666a9fe0d41bfc7b943c84bc00606e2705f952319f4cb2
6
+ metadata.gz: '08c1bea7f46add92b4bf6746ec3794a7845a0d0dccb8a8d338d7b3fd07133b670b5509bfd1a71fa10dcc11059bcd01b38a0da664c9fe7b86aa8d58738d0215e8'
7
+ data.tar.gz: 69efcb218b522cd233a593ccd281786732f76c717349f44c776a1a7f9790a697b46ccc63b60ab01b31b58ab38487c2d0c3ff3db7c99f55dd7fda469c1ecc5d90
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -411,8 +411,7 @@ module RubySMB
411
411
  raise RubySMB::Error::InvalidPacket.new(
412
412
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
413
413
  expected_cmd: RubySMB::SMB2::Packet::LogoffResponse::COMMAND,
414
- received_proto: response.smb2_header.protocol,
415
- received_cmd: response.smb2_header.command
414
+ packet: response
416
415
  )
417
416
  end
418
417
  else
@@ -423,8 +422,7 @@ module RubySMB
423
422
  raise RubySMB::Error::InvalidPacket.new(
424
423
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
425
424
  expected_cmd: RubySMB::SMB1::Packet::LogoffResponse::COMMAND,
426
- received_proto: response.smb_header.protocol,
427
- received_cmd: response.smb_header.command
425
+ packet: response
428
426
  )
429
427
  end
430
428
  end
@@ -473,11 +471,17 @@ module RubySMB
473
471
  break unless is_status_pending?(smb2_header)
474
472
  sleep 1
475
473
  raw_response = recv_packet(encrypt: encrypt_data)
474
+ rescue IOError
475
+ # We're expecting an SMB2 packet, but the server sent an SMB1 packet
476
+ # instead. This behavior has been observed with older versions of Samba
477
+ # when something goes wrong on the server side. So, we just ignore it
478
+ # and expect the caller to handle this wrong response packet.
479
+ break
476
480
  end unless version == 'SMB1'
477
481
 
478
482
  self.sequence_counter += 1 if signing_required && !session_key.empty?
479
483
  # update the SMB2 message ID according to the received Credit Charged
480
- self.smb2_message_id += smb2_header.credit_charge - 1 if smb2_header && self.dialect != '0x0202'
484
+ self.smb2_message_id += smb2_header.credit_charge - 1 if smb2_header && self.server_supports_multi_credit
481
485
  raw_response
482
486
  end
483
487
 
@@ -579,7 +583,7 @@ module RubySMB
579
583
  # @param [String] host
580
584
  def net_share_enum_all(host)
581
585
  tree = tree_connect("\\\\#{host}\\IPC$")
582
- named_pipe = tree.open_file(filename: "srvsvc", write: true, read: true)
586
+ named_pipe = tree.open_pipe(filename: "srvsvc", write: true, read: true)
583
587
  named_pipe.net_share_enum_all(host)
584
588
  end
585
589
 
@@ -60,8 +60,7 @@ module RubySMB
60
60
  raise RubySMB::Error::InvalidPacket.new(
61
61
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
62
62
  expected_cmd: RubySMB::SMB1::Packet::SessionSetupLegacyResponse::COMMAND,
63
- received_proto: packet.smb_header.protocol,
64
- received_cmd: packet.smb_header.command
63
+ packet: packet
65
64
  )
66
65
  end
67
66
  packet
@@ -154,8 +153,7 @@ module RubySMB
154
153
  raise RubySMB::Error::InvalidPacket.new(
155
154
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
156
155
  expected_cmd: RubySMB::SMB1::Packet::SessionSetupResponse::COMMAND,
157
- received_proto: packet.smb_header.protocol,
158
- received_cmd: packet.smb_header.command
156
+ packet: packet
159
157
  )
160
158
  end
161
159
  packet
@@ -168,8 +166,7 @@ module RubySMB
168
166
  raise RubySMB::Error::InvalidPacket.new(
169
167
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
170
168
  expected_cmd: RubySMB::SMB1::Packet::SessionSetupResponse::COMMAND,
171
- received_proto: packet.smb_header.protocol,
172
- received_cmd: packet.smb_header.command
169
+ packet: packet
173
170
  )
174
171
  end
175
172
 
@@ -236,8 +233,7 @@ module RubySMB
236
233
  raise RubySMB::Error::InvalidPacket.new(
237
234
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
238
235
  expected_cmd: RubySMB::SMB2::Packet::SessionSetupResponse::COMMAND,
239
- received_proto: packet.smb2_header.protocol,
240
- received_cmd: packet.smb2_header.command
236
+ packet: packet
241
237
  )
242
238
  end
243
239
 
@@ -251,8 +247,7 @@ module RubySMB
251
247
  raise RubySMB::Error::InvalidPacket.new(
252
248
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
253
249
  expected_cmd: RubySMB::SMB2::Packet::SessionSetupResponse::COMMAND,
254
- received_proto: packet.smb2_header.protocol,
255
- received_cmd: packet.smb2_header.command
250
+ packet: packet
256
251
  )
257
252
  end
258
253
 
@@ -21,8 +21,7 @@ module RubySMB
21
21
  raise RubySMB::Error::InvalidPacket.new(
22
22
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
23
23
  expected_cmd: RubySMB::SMB1::Packet::EchoResponse::COMMAND,
24
- received_proto: response.smb_header.protocol,
25
- received_cmd: response.smb_header.command
24
+ packet: response
26
25
  )
27
26
  end
28
27
  response
@@ -40,8 +39,7 @@ module RubySMB
40
39
  raise RubySMB::Error::InvalidPacket.new(
41
40
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
42
41
  expected_cmd: RubySMB::SMB2::Packet::EchoResponse::COMMAND,
43
- received_proto: response.smb2_header.protocol,
44
- received_cmd: response.smb2_header.command
42
+ packet: response
45
43
  )
46
44
  end
47
45
  response
@@ -83,16 +83,14 @@ module RubySMB
83
83
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
84
84
  expected_cmd: RubySMB::SMB1::Packet::NegotiateResponseExtended::COMMAND,
85
85
  expected_custom: "extended_security=1",
86
- received_proto: packet.smb_header.protocol,
87
- received_cmd: packet.smb_header.command,
86
+ packet: packet,
88
87
  received_custom: "extended_security=#{extended_security}"
89
88
  )
90
89
  elsif packet.packet_smb_version == 'SMB2'
91
90
  raise RubySMB::Error::InvalidPacket.new(
92
91
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
93
92
  expected_cmd: RubySMB::SMB2::Packet::NegotiateResponse::COMMAND,
94
- received_proto: packet.smb2_header.protocol,
95
- received_cmd: packet.smb2_header.command
93
+ packet: packet
96
94
  )
97
95
  else
98
96
  raise RubySMB::Error::InvalidPacket, 'Unknown SMB protocol version'
@@ -33,8 +33,7 @@ module RubySMB
33
33
  raise RubySMB::Error::InvalidPacket.new(
34
34
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
35
35
  expected_cmd: RubySMB::SMB1::Packet::TreeConnectResponse::COMMAND,
36
- received_proto: response.smb_header.protocol,
37
- received_cmd: response.smb_header.command
36
+ packet: response
38
37
  )
39
38
  end
40
39
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -73,8 +72,7 @@ module RubySMB
73
72
  raise RubySMB::Error::InvalidPacket.new(
74
73
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
75
74
  expected_cmd: RubySMB::SMB2::Packet::TreeConnectResponse::COMMAND,
76
- received_proto: response.smb2_header.protocol,
77
- received_cmd: response.smb2_header.command
75
+ packet: response
78
76
  )
79
77
  end
80
78
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -24,19 +24,25 @@ module RubySMB
24
24
  last_tree.id
25
25
  end
26
26
 
27
- def open(path, disposition=RubySMB::Dispositions::FILE_OPEN, write: false, read: true)
28
- file = last_tree.open_file(filename: path.sub(/^\\/, ''), write: write, read: read, disposition: disposition)
29
- @last_file_id = if file.respond_to?(:guid)
30
- file.guid.to_binary_s
31
- elsif file.respond_to?(:fid)
32
- file.fid.to_binary_s
33
- end
34
- @open_files[@last_file_id] = file
35
- @last_file_id
27
+ def open(path, disposition=RubySMB::Dispositions::FILE_OPEN, write: false, read: true, pipe: false)
28
+ if pipe
29
+ file = last_tree.open_pipe(filename: path, write: write, read: read, disposition: disposition)
30
+ else
31
+ file = last_tree.open_file(filename: path, write: write, read: read, disposition: disposition)
32
+ end
33
+ @last_file_id = if file.respond_to?(:guid)
34
+ # SMB2 uses guid
35
+ file.guid.to_binary_s
36
+ elsif file.respond_to?(:fid)
37
+ # SMB1 uses fid
38
+ file.fid.to_binary_s
39
+ end
40
+ @open_files[@last_file_id] = file
41
+ @last_file_id
36
42
  end
37
43
 
38
44
  def create_pipe(path, disposition=RubySMB::Dispositions::FILE_OPEN_IF)
39
- open(path.gsub(/\\/, ''), disposition, write: true, read: true)
45
+ open(path, disposition, write: true, read: true, pipe: true)
40
46
  end
41
47
 
42
48
  #Writes data to an open file handle
@@ -6,7 +6,7 @@ module RubySMB
6
6
  share = "\\\\#{host}\\IPC$"
7
7
  tree = @tree_connects.find {|tree| tree.share == share}
8
8
  tree = tree_connect(share) unless tree
9
- named_pipe = tree.open_file(filename: "winreg", write: true, read: true)
9
+ named_pipe = tree.open_pipe(filename: "winreg", write: true, read: true)
10
10
  if block_given?
11
11
  res = yield named_pipe
12
12
  named_pipe.close
@@ -387,7 +387,7 @@ module RubySMB
387
387
  enum_result
388
388
  ensure
389
389
  close_key(subkey_handle) if subkey_handle
390
- close_key(root_key_handle) if root_key_handle
390
+ close_key(root_key_handle) if root_key_handle && root_key_handle != subkey_handle
391
391
  end
392
392
 
393
393
  # Enumerate the values for the specified registry key.
@@ -413,7 +413,7 @@ module RubySMB
413
413
  enum_result
414
414
  ensure
415
415
  close_key(subkey_handle) if subkey_handle
416
- close_key(root_key_handle) if root_key_handle
416
+ close_key(root_key_handle) if root_key_handle && root_key_handle != subkey_handle
417
417
  end
418
418
 
419
419
  end
@@ -16,23 +16,26 @@ module RubySMB
16
16
  # Raised when trying to parse raw binary into a Packet and the data
17
17
  # is invalid.
18
18
  class InvalidPacket < RubySMBError
19
+ attr_reader :status_code
19
20
  def initialize(args = nil)
20
21
  if args.nil?
21
22
  super
22
23
  elsif args.is_a? String
23
24
  super(args)
24
25
  elsif args.is_a? Hash
25
- expected_proto = args[:expected_proto] ? translate_protocol(args[:expected_proto]) : "???"
26
- expected_cmd = args[:expected_cmd] || "???"
27
- received_proto = args[:received_proto] ? translate_protocol(args[:received_proto]) : "???"
28
- received_cmd = args[:received_cmd] || "???"
26
+ expected_proto = args[:expected_proto] ? translate_protocol(args[:expected_proto]) : '???'
27
+ expected_cmd = args[:expected_cmd] || '???'
28
+ received_proto = args[:packet]&.packet_smb_version || '???'
29
+ received_cmd = get_cmd(args[:packet]) || '???'
30
+ @status_code = args[:packet]&.status_code
29
31
  super(
30
32
  "Expecting #{expected_proto} protocol "\
31
33
  "with command=#{expected_cmd}"\
32
34
  "#{(" (" + args[:expected_custom] + ")") if args[:expected_custom]}, "\
33
35
  "got #{received_proto} protocol "\
34
36
  "with command=#{received_cmd}"\
35
- "#{(" (" + args[:received_custom] + ")") if args[:received_custom]}"
37
+ "#{(" (" + args[:received_custom] + ")") if args[:received_custom]}"\
38
+ "#{(", Status: #{@status_code}") if @status_code}"
36
39
  )
37
40
  else
38
41
  raise ArgumentError, "InvalidPacket expects a String or a Hash, got a #{args.class}"
@@ -50,6 +53,19 @@ module RubySMB
50
53
  end
51
54
  end
52
55
  private :translate_protocol
56
+
57
+ def get_cmd(packet)
58
+ return nil unless packet
59
+ case packet.packet_smb_version
60
+ when 'SMB1'
61
+ packet.smb_header.command
62
+ when 'SMB2'
63
+ packet.smb2_header.command
64
+ else
65
+ nil
66
+ end
67
+ end
68
+ private :get_cmd
53
69
  end
54
70
 
55
71
  # Raised when a response packet has a NTStatus code that was unexpected.
@@ -49,7 +49,17 @@ module RubySMB
49
49
  when /SMB1/
50
50
  packet = RubySMB::SMB1::Packet::EmptyPacket.read(val)
51
51
  when /SMB2/
52
- packet = RubySMB::SMB2::Packet::ErrorPacket.read(val)
52
+ begin
53
+ packet = RubySMB::SMB2::Packet::ErrorPacket.read(val)
54
+ rescue RubySMB::Error::InvalidPacket
55
+ # Handle the case where an SMB2 error packet is expected, but the
56
+ # server sent an SMB1 empty packet instead. This behavior has been
57
+ # observed with older versions of Samba when something goes wrong
58
+ # on the server side. We just want to give it a chance and try to
59
+ # parse it as an SMB1 empty packet to keep information and avoid
60
+ # failing as much as possible.
61
+ packet = RubySMB::SMB1::Packet::EmptyPacket.read(val)
62
+ end
53
63
  else
54
64
  raise RubySMB::Error::InvalidPacket, 'Not a valid SMB packet'
55
65
  end
@@ -86,8 +86,7 @@ module RubySMB
86
86
  raise RubySMB::Error::InvalidPacket.new(
87
87
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
88
88
  expected_cmd: RubySMB::SMB1::Packet::CloseResponse::COMMAND,
89
- received_proto: response.smb_header.protocol,
90
- received_cmd: response.smb_header.command
89
+ packet: response
91
90
  )
92
91
  end
93
92
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -118,8 +117,7 @@ module RubySMB
118
117
  raise RubySMB::Error::InvalidPacket.new(
119
118
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
120
119
  expected_cmd: RubySMB::SMB1::Packet::ReadAndxResponse::COMMAND,
121
- received_proto: response.smb_header.protocol,
122
- received_cmd: response.smb_header.command
120
+ packet: response
123
121
  )
124
122
  end
125
123
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -167,8 +165,7 @@ module RubySMB
167
165
  raise RubySMB::Error::InvalidPacket.new(
168
166
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
169
167
  expected_cmd: RubySMB::SMB1::Packet::ReadAndxResponse::COMMAND,
170
- received_proto: response.smb_header.protocol,
171
- received_cmd: response.smb_header.command
168
+ packet: response
172
169
  )
173
170
  end
174
171
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -189,8 +186,7 @@ module RubySMB
189
186
  raise RubySMB::Error::InvalidPacket.new(
190
187
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
191
188
  expected_cmd: RubySMB::SMB1::Packet::Trans2::SetFileInformationResponse::COMMAND,
192
- received_proto: response.smb_header.protocol,
193
- received_cmd: response.smb_header.command
189
+ packet: response
194
190
  )
195
191
  end
196
192
  response.status_code
@@ -231,8 +227,7 @@ module RubySMB
231
227
  raise RubySMB::Error::InvalidPacket.new(
232
228
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
233
229
  expected_cmd: RubySMB::SMB1::Packet::WriteAndxResponse::COMMAND,
234
- received_proto: response.smb_header.protocol,
235
- received_cmd: response.smb_header.command
230
+ packet: response
236
231
  )
237
232
  end
238
233
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -271,8 +266,7 @@ module RubySMB
271
266
  raise RubySMB::Error::InvalidPacket.new(
272
267
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
273
268
  expected_cmd: RubySMB::SMB1::Packet::WriteAndxResponse::COMMAND,
274
- received_proto: response.smb_header.protocol,
275
- received_cmd: response.smb_header.command
269
+ packet: response
276
270
  )
277
271
  end
278
272
  response.parameter_block.count_low
@@ -290,8 +284,7 @@ module RubySMB
290
284
  raise RubySMB::Error::InvalidPacket.new(
291
285
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
292
286
  expected_cmd: RubySMB::SMB1::Packet::Trans2::SetFileInformationResponse::COMMAND,
293
- received_proto: response.smb_header.protocol,
294
- received_cmd: response.smb_header.command
287
+ packet: response
295
288
  )
296
289
  end
297
290
  response.status_code
@@ -16,11 +16,11 @@ module RubySMB
16
16
  def initialize(tree:, response:, name:)
17
17
  raise ArgumentError, 'No Name Provided' if name.nil?
18
18
  case name
19
- when 'srvsvc'
19
+ when 'srvsvc', '\\srvsvc'
20
20
  extend RubySMB::Dcerpc::Srvsvc
21
- when 'winreg'
21
+ when 'winreg', '\\winreg'
22
22
  extend RubySMB::Dcerpc::Winreg
23
- when 'svcctl'
23
+ when 'svcctl', '\\svcctl'
24
24
  extend RubySMB::Dcerpc::Svcctl
25
25
  end
26
26
  super(tree: tree, response: response, name: name)
@@ -43,8 +43,7 @@ module RubySMB
43
43
  raise RubySMB::Error::InvalidPacket.new(
44
44
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
45
45
  expected_cmd: RubySMB::SMB1::Packet::Trans::PeekNmpipeRequest::COMMAND,
46
- received_proto: response.smb_header.protocol,
47
- received_cmd: response.smb_header.command
46
+ packet: response
48
47
  )
49
48
  end
50
49
 
@@ -102,8 +101,7 @@ module RubySMB
102
101
  raise RubySMB::Error::InvalidPacket.new(
103
102
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
104
103
  expected_cmd: RubySMB::SMB1::Packet::Trans::TransactNmpipeResponse::COMMAND,
105
- received_proto: trans_nmpipe_response.smb_header.protocol,
106
- received_cmd: trans_nmpipe_response.smb_header.command
104
+ packet: trans_nmpipe_response
107
105
  )
108
106
  end
109
107
  unless [WindowsError::NTStatus::STATUS_SUCCESS,
@@ -49,13 +49,20 @@ module RubySMB
49
49
  raise RubySMB::Error::InvalidPacket.new(
50
50
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
51
51
  expected_cmd: RubySMB::SMB1::Packet::TreeDisconnectResponse::COMMAND,
52
- received_proto: response.smb_header.protocol,
53
- received_cmd: response.smb_header.command
52
+ packet: response
54
53
  )
55
54
  end
56
55
  response.status_code
57
56
  end
58
57
 
58
+ def open_pipe(opts)
59
+ # Make sure we don't modify the caller's hash options
60
+ opts = opts.dup
61
+ opts[:filename] = opts[:filename].dup
62
+ opts[:filename].prepend('\\') unless opts[:filename].start_with?('\\')
63
+ open_file(opts)
64
+ end
65
+
59
66
  # Open a file on the remote share.
60
67
  #
61
68
  # @example
@@ -135,15 +142,14 @@ module RubySMB
135
142
  raise RubySMB::Error::InvalidPacket.new(
136
143
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
137
144
  expected_cmd: RubySMB::SMB1::Packet::NtCreateAndxResponse::COMMAND,
138
- received_proto: response.smb_header.protocol,
139
- received_cmd: response.smb_header.command
145
+ packet: response
140
146
  )
141
147
  end
142
148
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
143
149
  raise RubySMB::Error::UnexpectedStatusCode, response.status_code
144
150
  end
145
151
 
146
- case response.parameter_block.resource_type
152
+ case response.parameter_block.resource_type
147
153
  when RubySMB::SMB1::ResourceType::BYTE_MODE_PIPE, RubySMB::SMB1::ResourceType::MESSAGE_MODE_PIPE
148
154
  RubySMB::SMB1::Pipe.new(name: filename, tree: self, response: response)
149
155
  when RubySMB::SMB1::ResourceType::DISK
@@ -195,8 +201,7 @@ module RubySMB
195
201
  raise RubySMB::Error::InvalidPacket.new(
196
202
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
197
203
  expected_cmd: RubySMB::SMB1::Packet::Trans2::FindFirst2Response::COMMAND,
198
- received_proto: response.smb_header.protocol,
199
- received_cmd: response.smb_header.command
204
+ packet: response
200
205
  )
201
206
  end
202
207
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -230,8 +235,7 @@ module RubySMB
230
235
  raise RubySMB::Error::InvalidPacket.new(
231
236
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
232
237
  expected_cmd: RubySMB::SMB1::Packet::Trans2::FindNext2Response::COMMAND,
233
- received_proto: response.smb_header.protocol,
234
- received_cmd: response.smb_header.command
238
+ packet: response
235
239
  )
236
240
  end
237
241
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -95,8 +95,7 @@ module RubySMB
95
95
  raise RubySMB::Error::InvalidPacket.new(
96
96
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
97
97
  expected_cmd: RubySMB::SMB2::Packet::CloseResponse::COMMAND,
98
- received_proto: response.smb2_header.protocol,
99
- received_cmd: response.smb2_header.command
98
+ packet: response
100
99
  )
101
100
  end
102
101
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -130,8 +129,7 @@ module RubySMB
130
129
  raise RubySMB::Error::InvalidPacket.new(
131
130
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
132
131
  expected_cmd: RubySMB::SMB2::Packet::ReadResponse::COMMAND,
133
- received_proto: response.smb2_header.protocol,
134
- received_cmd: response.smb2_header.command
132
+ packet: response
135
133
  )
136
134
  end
137
135
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -153,8 +151,7 @@ module RubySMB
153
151
  raise RubySMB::Error::InvalidPacket.new(
154
152
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
155
153
  expected_cmd: RubySMB::SMB2::Packet::ReadResponse::COMMAND,
156
- received_proto: response.smb2_header.protocol,
157
- received_cmd: response.smb2_header.command
154
+ packet: response
158
155
  )
159
156
  end
160
157
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -189,8 +186,7 @@ module RubySMB
189
186
  raise RubySMB::Error::InvalidPacket.new(
190
187
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
191
188
  expected_cmd: RubySMB::SMB2::Packet::ReadResponse::COMMAND,
192
- received_proto: response.smb2_header.protocol,
193
- received_cmd: response.smb2_header.command
189
+ packet: response
194
190
  )
195
191
  end
196
192
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -210,8 +206,7 @@ module RubySMB
210
206
  raise RubySMB::Error::InvalidPacket.new(
211
207
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
212
208
  expected_cmd: RubySMB::SMB2::Packet::SetInfoResponse::COMMAND,
213
- received_proto: response.smb2_header.protocol,
214
- received_cmd: response.smb2_header.command
209
+ packet: response
215
210
  )
216
211
  end
217
212
  response.smb2_header.nt_status.to_nt_status
@@ -262,8 +257,7 @@ module RubySMB
262
257
  raise RubySMB::Error::InvalidPacket.new(
263
258
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
264
259
  expected_cmd: RubySMB::SMB2::Packet::WriteResponse::COMMAND,
265
- received_proto: response.smb2_header.protocol,
266
- received_cmd: response.smb2_header.command
260
+ packet: response
267
261
  )
268
262
  end
269
263
  status = response.smb2_header.nt_status.to_nt_status
@@ -297,8 +291,7 @@ module RubySMB
297
291
  raise RubySMB::Error::InvalidPacket.new(
298
292
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
299
293
  expected_cmd: RubySMB::SMB2::Packet::WriteResponse::COMMAND,
300
- received_proto: response.smb2_header.protocol,
301
- received_cmd: response.smb2_header.command
294
+ packet: response
302
295
  )
303
296
  end
304
297
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -319,8 +312,7 @@ module RubySMB
319
312
  raise RubySMB::Error::InvalidPacket.new(
320
313
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
321
314
  expected_cmd: RubySMB::SMB2::Packet::SetInfoResponse::COMMAND,
322
- received_proto: response.smb2_header.protocol,
323
- received_cmd: response.smb2_header.command
315
+ packet: response
324
316
  )
325
317
  end
326
318
  response.smb2_header.nt_status.to_nt_status
@@ -42,8 +42,7 @@ module RubySMB
42
42
  raise RubySMB::Error::InvalidPacket.new(
43
43
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
44
44
  expected_cmd: RubySMB::SMB2::Packet::IoctlResponse::COMMAND,
45
- received_proto: response.smb2_header.protocol,
46
- received_cmd: response.smb2_header.command
45
+ packet: response
47
46
  )
48
47
  end
49
48
 
@@ -100,8 +99,7 @@ module RubySMB
100
99
  raise RubySMB::Error::InvalidPacket.new(
101
100
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
102
101
  expected_cmd: RubySMB::SMB2::Packet::IoctlRequest::COMMAND,
103
- received_proto: ioctl_response.smb2_header.protocol,
104
- received_cmd: ioctl_response.smb2_header.command
102
+ packet: ioctl_response
105
103
  )
106
104
  end
107
105
  unless [WindowsError::NTStatus::STATUS_SUCCESS,
@@ -50,13 +50,20 @@ module RubySMB
50
50
  raise RubySMB::Error::InvalidPacket.new(
51
51
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
52
52
  expected_cmd: RubySMB::SMB2::Packet::TreeDisconnectResponse::COMMAND,
53
- received_proto: response.smb2_header.protocol,
54
- received_cmd: response.smb2_header.command
53
+ packet: response
55
54
  )
56
55
  end
57
56
  response.status_code
58
57
  end
59
58
 
59
+ def open_pipe(opts)
60
+ # Make sure we don't modify the caller's hash options
61
+ opts = opts.dup
62
+ opts[:filename] = opts[:filename].dup
63
+ opts[:filename] = opts[:filename][1..-1] if opts[:filename].start_with? '\\'
64
+ open_file(opts)
65
+ end
66
+
60
67
  def open_file(filename:, attributes: nil, options: nil, disposition: RubySMB::Dispositions::FILE_OPEN,
61
68
  impersonation: RubySMB::ImpersonationLevels::SEC_IMPERSONATE, read: true, write: false, delete: false)
62
69
 
@@ -108,8 +115,7 @@ module RubySMB
108
115
  raise RubySMB::Error::InvalidPacket.new(
109
116
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
110
117
  expected_cmd: RubySMB::SMB2::Packet::CreateResponse::COMMAND,
111
- received_proto: response.smb2_header.protocol,
112
- received_cmd: response.smb2_header.command
118
+ packet: response
113
119
  )
114
120
  end
115
121
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -167,8 +173,7 @@ module RubySMB
167
173
  raise RubySMB::Error::InvalidPacket.new(
168
174
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
169
175
  expected_cmd: RubySMB::SMB2::Packet::QueryDirectoryResponse::COMMAND,
170
- received_proto: directory_response.smb2_header.protocol,
171
- received_cmd: directory_response.smb2_header.command
176
+ packet: directory_response
172
177
  )
173
178
  end
174
179
 
@@ -212,8 +217,7 @@ module RubySMB
212
217
  raise RubySMB::Error::InvalidPacket.new(
213
218
  expected_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
214
219
  expected_cmd: RubySMB::SMB2::Packet::CreateResponse::COMMAND,
215
- received_proto: response.smb2_header.protocol,
216
- received_cmd: response.smb2_header.command
220
+ packet: response
217
221
  )
218
222
  end
219
223
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -1,3 +1,3 @@
1
1
  module RubySMB
2
- VERSION = '2.0.3'.freeze
2
+ VERSION = '2.0.4'.freeze
3
3
  end
@@ -332,23 +332,28 @@ RSpec.describe RubySMB::Client do
332
332
  expect(smb2_client.sequence_counter).to eq(1)
333
333
  end
334
334
 
335
- it 'updates #msb2_message_id with SMB2 header #credit_charge if the dialect is not 0x0202' do
335
+ it 'updates #smb2_message_id with SMB2 header #credit_charge if the server supports multi credits' do
336
336
  allow(smb2_client).to receive(:is_status_pending?).and_return(false)
337
337
  smb2_client.smb2_message_id = 0
338
- smb2_client.dialect = '0x0210'
338
+ smb2_client.server_supports_multi_credit = true
339
339
  smb2_header.credit_charge = 5
340
340
  smb2_client.send_recv(smb2_request)
341
341
  expect(smb2_client.smb2_message_id).to eq(5)
342
342
  end
343
343
 
344
- it 'does not update #msb2_message_id with SMB2 header #credit_charge if the dialect is 0x0202' do
344
+ it 'does not update #msb2_message_id with SMB2 header #credit_charge if the server does not support multi credits' do
345
345
  allow(smb2_client).to receive(:is_status_pending?).and_return(false)
346
346
  smb2_client.smb2_message_id = 0
347
- smb2_client.dialect = '0x0202'
347
+ smb2_client.server_supports_multi_credit = false
348
348
  smb2_header.credit_charge = 5
349
349
  smb2_client.send_recv(smb2_request)
350
350
  expect(smb2_client.smb2_message_id).to eq(1)
351
351
  end
352
+
353
+ it 'ignores errors thrown when parsing the SMB2 header' do
354
+ allow(RubySMB::SMB2::SMB2Header).to receive(:read).and_raise(IOError)
355
+ expect { smb2_client.send_recv(smb2_request) }.to_not raise_error
356
+ end
352
357
  end
353
358
 
354
359
  describe '#is_status_pending?' do
@@ -2354,7 +2359,7 @@ RSpec.describe RubySMB::Client do
2354
2359
  let(:named_pipe){ double("Named Pipe") }
2355
2360
 
2356
2361
  before :example do
2357
- allow(tree).to receive(:open_file).and_return(named_pipe)
2362
+ allow(tree).to receive(:open_pipe).and_return(named_pipe)
2358
2363
  allow(named_pipe).to receive(:net_share_enum_all)
2359
2364
  end
2360
2365
 
@@ -2369,8 +2374,8 @@ RSpec.describe RubySMB::Client do
2369
2374
  smb1_client.net_share_enum_all(sock.peeraddr)
2370
2375
  end
2371
2376
 
2372
- it 'it calls the Tree #open_file method to open "srvsvc" named pipe' do
2373
- expect(tree).to receive(:open_file).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
2377
+ it 'it calls the Tree #open_pipe method to open "srvsvc" named pipe' do
2378
+ expect(tree).to receive(:open_pipe).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
2374
2379
  smb1_client.net_share_enum_all(sock.peeraddr)
2375
2380
  end
2376
2381
 
@@ -2392,8 +2397,8 @@ RSpec.describe RubySMB::Client do
2392
2397
  smb2_client.net_share_enum_all(sock.peeraddr)
2393
2398
  end
2394
2399
 
2395
- it 'it calls the Tree #open_file method to open "srvsvc" named pipe' do
2396
- expect(tree).to receive(:open_file).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
2400
+ it 'it calls the Tree #open_pipe method to open "srvsvc" named pipe' do
2401
+ expect(tree).to receive(:open_pipe).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
2397
2402
  smb2_client.net_share_enum_all(sock.peeraddr)
2398
2403
  end
2399
2404
 
@@ -2474,7 +2479,7 @@ RSpec.describe RubySMB::Client do
2474
2479
  before :example do
2475
2480
  allow(ipc_tree).to receive_messages(
2476
2481
  :share => share,
2477
- :open_file => named_pipe
2482
+ :open_pipe => named_pipe
2478
2483
  )
2479
2484
  allow(client).to receive(:tree_connect).and_return(ipc_tree)
2480
2485
  end
@@ -2496,9 +2501,9 @@ RSpec.describe RubySMB::Client do
2496
2501
  expect(client).to have_received(:tree_connect).with(share)
2497
2502
  end
2498
2503
 
2499
- it 'open \'winreg\' file on the IPC$ Tree' do
2504
+ it 'open \'winreg\' pipe on the IPC$ Tree' do
2500
2505
  client.connect_to_winreg(host)
2501
- expect(ipc_tree).to have_received(:open_file).with(filename: "winreg", write: true, read: true)
2506
+ expect(ipc_tree).to have_received(:open_pipe).with(filename: "winreg", write: true, read: true)
2502
2507
  end
2503
2508
 
2504
2509
  it 'returns the expected opened named pipe' do
@@ -669,6 +669,12 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
669
669
  expect(winreg).to have_received(:close_key).with(root_key_handle)
670
670
  end
671
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)
676
+ end
677
+
672
678
  it 'returns the expected array of enumerated keys' do
673
679
  key1 = 'key1'
674
680
  key2 = 'key2'
@@ -742,6 +748,12 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
742
748
  expect(winreg).to have_received(:close_key).with(root_key_handle)
743
749
  end
744
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)
755
+ end
756
+
745
757
  it 'returns the expected array of enumerated keys' do
746
758
  value1 = 'value1'
747
759
  value2 = 'value2'
@@ -9,16 +9,45 @@ RSpec.describe RubySMB::Error::InvalidPacket do
9
9
  end
10
10
 
11
11
  context 'with a Hash' do
12
- it 'outputs the expected error message' do
13
- ex = described_class.new(
12
+ let(:ex) do
13
+ described_class.new(
14
14
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
15
15
  expected_cmd: RubySMB::SMB1::Packet::NegotiateResponseExtended::COMMAND,
16
16
  expected_custom: "extended_security=1",
17
- received_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
18
- received_cmd: RubySMB::SMB2::Packet::NegotiateResponse::COMMAND,
17
+ packet: packet,
19
18
  received_custom: "extended_security=0"
20
19
  )
21
- expect(ex.to_s).to eq('Expecting SMB1 protocol with command=114 (extended_security=1), got SMB2 protocol with command=0 (extended_security=0)')
20
+ end
21
+
22
+ context 'with an SMB2 packet' do
23
+ let(:packet) { RubySMB::SMB2::Packet::NegotiateResponse.new }
24
+
25
+ it 'outputs the expected error message' do
26
+ expect(ex.to_s).to eq('Expecting SMB1 protocol with command=114 (extended_security=1), got SMB2 protocol with command=0 (extended_security=0), Status: (0x00000000) STATUS_SUCCESS: The operation completed successfully.')
27
+ end
28
+ end
29
+
30
+ context 'with an SMB1 packet' do
31
+ let(:packet) { RubySMB::SMB1::Packet::ReadAndxRequest.new }
32
+
33
+ it 'outputs the expected error message' do
34
+ expect(ex.to_s).to eq('Expecting SMB1 protocol with command=114 (extended_security=1), got SMB1 protocol with command=46 (extended_security=0), Status: (0x00000000) STATUS_SUCCESS: The operation completed successfully.')
35
+ end
36
+ end
37
+
38
+ context 'without packet' do
39
+ let(:ex) do
40
+ described_class.new(
41
+ expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
42
+ expected_cmd: RubySMB::SMB1::Packet::NegotiateResponseExtended::COMMAND,
43
+ expected_custom: "extended_security=1",
44
+ received_custom: "extended_security=0"
45
+ )
46
+ end
47
+
48
+ it 'outputs the expected error message' do
49
+ expect(ex.to_s).to eq('Expecting SMB1 protocol with command=114 (extended_security=1), got ??? protocol with command=??? (extended_security=0)')
50
+ end
22
51
  end
23
52
  end
24
53
 
@@ -88,6 +88,13 @@ RSpec.describe RubySMB::GenericPacket do
88
88
  packet = RubySMB::SMB2::Packet::NegotiateResponse.read(smb2_error_packet.to_binary_s)
89
89
  expect(packet.original_command).to eq RubySMB::SMB2::Packet::NegotiateResponse::COMMAND
90
90
  end
91
+
92
+ context 'when the server returns an SMB1 error packet' do
93
+ let(:smb1_error_packet) { RubySMB::SMB1::Packet::EmptyPacket.new }
94
+ it 'returns the empty packet instead of the asked for class' do
95
+ expect(RubySMB::SMB2::Packet::NegotiateResponse.read(smb1_error_packet.to_binary_s)).to be_a RubySMB::SMB1::Packet::EmptyPacket
96
+ end
97
+ end
91
98
  end
92
99
  end
93
100
 
@@ -521,9 +521,7 @@ RSpec.describe RubySMB::SMB1::File do
521
521
 
522
522
  it 'raises an InvalidPacket exception if the response is not valid' do
523
523
  allow(response).to receive(:valid?).and_return(false)
524
- smb_header = double('SMB Header')
525
- allow(response).to receive(:smb_header).and_return(smb_header)
526
- allow(smb_header).to receive_messages(:protocol => nil, :command => nil)
524
+ allow(response).to receive(:packet_smb_version)
527
525
  expect { file.close }.to raise_error(RubySMB::Error::InvalidPacket)
528
526
  end
529
527
 
@@ -80,9 +80,7 @@ RSpec.describe RubySMB::SMB1::Pipe do
80
80
 
81
81
  it 'raises an InvalidPacket exception if the response is not valid' do
82
82
  allow(response).to receive(:valid?).and_return(false)
83
- smb_header = double('SMB Header')
84
- allow(response).to receive(:smb_header).and_return(smb_header)
85
- allow(smb_header).to receive_messages(:protocol => nil, :command => nil)
83
+ allow(response).to receive(:packet_smb_version)
86
84
  expect { pipe.peek }.to raise_error(RubySMB::Error::InvalidPacket)
87
85
  end
88
86
 
@@ -149,6 +147,13 @@ RSpec.describe RubySMB::SMB1::Pipe do
149
147
  end
150
148
  end
151
149
 
150
+ context 'with \'\\srvsvc\' filename' do
151
+ it 'extends Srvsvc class' do
152
+ pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: '\\srvsvc')
153
+ expect(pipe.respond_to?(:net_share_enum_all)).to be true
154
+ end
155
+ end
156
+
152
157
  context 'with \'winreg\' filename' do
153
158
  it 'extends Winreg class' do
154
159
  pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: 'winreg')
@@ -156,12 +161,26 @@ RSpec.describe RubySMB::SMB1::Pipe do
156
161
  end
157
162
  end
158
163
 
164
+ context 'with \'\\winreg\' filename' do
165
+ it 'extends Winreg class' do
166
+ pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: '\\winreg')
167
+ expect(pipe.respond_to?(:has_registry_key?)).to be true
168
+ end
169
+ end
170
+
159
171
  context 'with \'svcctl\' filename' do
160
172
  it 'extends svcctl class' do
161
173
  pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: 'svcctl')
162
174
  expect(pipe.respond_to?(:query_service_config)).to be true
163
175
  end
164
176
  end
177
+
178
+ context 'with \'\\svcctl\' filename' do
179
+ it 'extends svcctl class' do
180
+ pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: '\\svcctl')
181
+ expect(pipe.respond_to?(:query_service_config)).to be true
182
+ end
183
+ end
165
184
  end
166
185
 
167
186
  describe '#dcerpc_request' do
@@ -245,8 +264,7 @@ RSpec.describe RubySMB::SMB1::Pipe do
245
264
 
246
265
  context 'when the response is not a Trans packet' do
247
266
  it 'raises an InvalidPacket exception' do
248
- allow(trans_nmpipe_response).to receive_message_chain(:smb_header, :protocol)
249
- allow(trans_nmpipe_response).to receive_message_chain(:smb_header, :command)
267
+ allow(trans_nmpipe_response).to receive(:packet_smb_version)
250
268
  allow(trans_nmpipe_response).to receive(:valid?).and_return(false)
251
269
  expect { pipe.dcerpc_request(stub_packet, options) }.to raise_error(RubySMB::Error::InvalidPacket)
252
270
  end
@@ -492,4 +492,26 @@ RSpec.describe RubySMB::SMB1::Tree do
492
492
  end
493
493
  end
494
494
 
495
+ describe '#open_pipe' do
496
+ let(:opts) { { filename: 'test', write: true } }
497
+ before :example do
498
+ allow(tree).to receive(:open_file)
499
+ end
500
+
501
+ it 'calls #open_file with the provided options' do
502
+ opts[:filename] ='\\test'
503
+ expect(tree).to receive(:open_file).with(opts)
504
+ tree.open_pipe(opts)
505
+ end
506
+
507
+ it 'prepends the filename with \\ if needed' do
508
+ expect(tree).to receive(:open_file).with( { filename: '\\test', write: true } )
509
+ tree.open_pipe(opts)
510
+ end
511
+
512
+ it 'does not modify the original option hash' do
513
+ tree.open_pipe(opts)
514
+ expect(opts).to eq( { filename: 'test', write: true } )
515
+ end
516
+ end
495
517
  end
@@ -459,9 +459,7 @@ RSpec.describe RubySMB::SMB2::File do
459
459
 
460
460
  it 'raises an InvalidPacket exception if the response is not valid' do
461
461
  allow(response).to receive(:valid?).and_return(false)
462
- smb2_header = double('SMB2 Header')
463
- allow(response).to receive(:smb2_header).and_return(smb2_header)
464
- allow(smb2_header).to receive_messages(:protocol => nil, :command => nil)
462
+ allow(response).to receive(:packet_smb_version)
465
463
  expect { file.close }.to raise_error(RubySMB::Error::InvalidPacket)
466
464
  end
467
465
 
@@ -86,9 +86,7 @@ RSpec.describe RubySMB::SMB2::Pipe do
86
86
 
87
87
  it 'raises an InvalidPacket exception if the response is not valid' do
88
88
  allow(response).to receive(:valid?).and_return(false)
89
- smb2_header = double('SMB2 Header')
90
- allow(response).to receive(:smb2_header).and_return(smb2_header)
91
- allow(smb2_header).to receive_messages(:protocol => nil, :command => nil)
89
+ allow(response).to receive(:packet_smb_version)
92
90
  expect { pipe.peek }.to raise_error(RubySMB::Error::InvalidPacket)
93
91
  end
94
92
 
@@ -261,8 +259,7 @@ RSpec.describe RubySMB::SMB2::Pipe do
261
259
 
262
260
  context 'when the response is not an IoctlResponse packet' do
263
261
  it 'raises an InvalidPacket exception' do
264
- allow(ioctl_response).to receive_message_chain(:smb2_header, :protocol)
265
- allow(ioctl_response).to receive_message_chain(:smb2_header, :command)
262
+ allow(ioctl_response).to receive(:packet_smb_version)
266
263
  allow(ioctl_response).to receive(:valid?).and_return(false)
267
264
  expect { pipe.ioctl_send_recv(dcerpc_request, options) }.to raise_error(RubySMB::Error::InvalidPacket)
268
265
  end
@@ -531,4 +531,27 @@ RSpec.describe RubySMB::SMB2::Tree do
531
531
  end
532
532
  end
533
533
  end
534
+
535
+ describe '#open_pipe' do
536
+ let(:opts) { { filename: '\\test', write: true } }
537
+ before :example do
538
+ allow(tree).to receive(:open_file)
539
+ end
540
+
541
+ it 'calls #open_file with the provided options' do
542
+ opts[:filename] ='test'
543
+ expect(tree).to receive(:open_file).with(opts)
544
+ tree.open_pipe(opts)
545
+ end
546
+
547
+ it 'remove the leading \\ from the filename if needed' do
548
+ expect(tree).to receive(:open_file).with( { filename: 'test', write: true } )
549
+ tree.open_pipe(opts)
550
+ end
551
+
552
+ it 'does not modify the original option hash' do
553
+ tree.open_pipe(opts)
554
+ expect(opts).to eq( { filename: '\\test', write: true } )
555
+ end
556
+ end
534
557
  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: 2.0.3
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -97,7 +97,7 @@ cert_chain:
97
97
  JI/W23RbIRksG2pioMhd4dCXq3FLLlkOV1YfCwWixNB+iIhQPPZVaPNfgPhCn4Dt
98
98
  DeGjje/qA4fkLtRmOtb9PUBq3ToRDE4=
99
99
  -----END CERTIFICATE-----
100
- date: 2020-08-17 00:00:00.000000000 Z
100
+ date: 2020-08-28 00:00:00.000000000 Z
101
101
  dependencies:
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: redcarpet
metadata.gz.sig CHANGED
@@ -1 +1,2 @@
1
- N�� H-
1
+ CpfDǵ�&K��:�Sm�h�t ���HI��Ă) !����A
2
+ �\ҝ�1��-�ق*��D��o��i����a=�h�o�df�E���`GLU�W&O�~�*'�d'UU�%�M2�c[�YG���@2>�M�<�n6��Χm�qg3 "n(��\�O�� �5��w�c�<rf�f�[�!��_�����I����S�,�bf�9��R�U��UZ3�<(mj(��uN7E�����0�������0�Z