class Rex::Proto::SMB::SimpleClient::OpenFile

Attributes

chunk_size[RW]
client[RW]
file_id[RW]
mode[RW]
name[RW]
tree_id[RW]

Public Class Methods

new(client, name, tree_id, file_id) click to toggle source
# File lib/rex/proto/smb/simpleclient/open_file.rb, line 9
def initialize(client, name, tree_id, file_id)
  self.client = client
  self.name = name
  self.tree_id = tree_id
  self.file_id = file_id
  self.chunk_size = 48000
end

Public Instance Methods

<<(data) click to toggle source
# File lib/rex/proto/smb/simpleclient/open_file.rb, line 71
def << (data)
  self.write(data)
end
close() click to toggle source

Close this open file

# File lib/rex/proto/smb/simpleclient/open_file.rb, line 26
def close
  self.client.close(self.file_id, self.tree_id)
end
delete() click to toggle source
# File lib/rex/proto/smb/simpleclient/open_file.rb, line 17
def delete
  begin
    self.close
  rescue
  end
  self.client.delete(self.name, self.tree_id)
end
read(length = nil, offset = 0) click to toggle source

Read data from the file

# File lib/rex/proto/smb/simpleclient/open_file.rb, line 31
def read(length = nil, offset = 0)
  if (length == nil)
    data = ''
    fptr = offset
    ok = self.client.read(self.file_id, fptr, self.chunk_size)
    while (ok and ok['Payload'].v['DataLenLow'] > 0)
      buff = ok.to_s.slice(
        ok['Payload'].v['DataOffset'] + 4,
        ok['Payload'].v['DataLenLow']
      )
      data << buff
      if ok['Payload'].v['Remaining'] == 0
        break
      end
      fptr += ok['Payload'].v['DataLenLow']

      begin
        ok = self.client.read(self.file_id, fptr, self.chunk_size)
      rescue XCEPT::ErrorCode => e
        case e.error_code
        when 0x00050001
          # Novell fires off an access denied error on EOF
          ok = nil
        else
          raise e
        end
      end
    end

    return data
  else
    ok = self.client.read(self.file_id, offset, length)
    data = ok.to_s.slice(
      ok['Payload'].v['DataOffset'] + 4,
      ok['Payload'].v['DataLenLow']
    )
    return data
  end
end
write(data, offset = 0) click to toggle source

Write data to the file

# File lib/rex/proto/smb/simpleclient/open_file.rb, line 76
def write(data, offset = 0)
  # Track our offset into the remote file
  fptr = offset

  # Duplicate the data so we can use slice!
  data = data.dup

  # Take our first chunk of bytes
  chunk = data.slice!(0, self.chunk_size)

  # Keep writing data until we run out
  while (chunk.length > 0)
    ok = self.client.write(self.file_id, fptr, chunk)
    cl = ok['Payload'].v['CountLow']

    # Partial write, push the failed data back into the queue
    if (cl != chunk.length)
      data = chunk.slice(cl - 1, chunk.length - cl) + data
    end

    # Increment our painter and grab the next chunk
    fptr += cl
    chunk = data.slice!(0, self.chunk_size)
  end
end