metasploit-framework/lib/rex/proto/pjl/client.rb

163 lines
3.0 KiB
Ruby

# https://en.wikipedia.org/wiki/Printer_Job_Language
# See external links for PJL spec
module Rex::Proto::PJL
class Client
attr_reader :sock
def initialize(sock)
@sock = sock
end
# Begin a PJL job
#
# @return [void]
def begin_job
@sock.put("#{UEL}#{PREFIX}\n")
end
# End a PJL job
#
# @return [void]
def end_job
@sock.put(UEL)
end
# Send an INFO request and read the response
#
# @param category [String] INFO category
# @return [String] INFO response
def info(category)
categories = {
:id => Info::ID,
:status => Info::STATUS,
:variables => Info::VARIABLES,
:filesys => Info::FILESYS
}
unless categories.has_key?(category)
raise ArgumentError, "Unknown INFO category"
end
@sock.put("#{categories[category]}\n")
@sock.get(DEFAULT_TIMEOUT)
end
# Get version information
#
# @return [String] Version information
def info_id
id = nil
if info(:id) =~ /"(.*?)"/m
id = $1
end
id
end
# Get environment variables
#
# @return [String] Environment variables
def info_variables
env_vars = nil
if info(:variables) =~ /#{Info::VARIABLES}\r?\n(.*?)\f/m
env_vars = $1
end
env_vars
end
# List volumes
#
# @return [String] Volume listing
def info_filesys
filesys = nil
if info(:filesys) =~ /\[\d+ TABLE\]\r?\n(.*?)\f/m
filesys = $1
end
filesys
end
# Get the ready message
#
# @return [String] Ready message
def get_rdymsg
rdymsg = nil
if info(:status) =~ /DISPLAY="(.*?)"/m
rdymsg = $1
end
rdymsg
end
# Set the ready message
#
# @param message [String] Ready message
# @return [void]
def set_rdymsg(message)
@sock.put(%Q{#{RDYMSG} DISPLAY = "#{message}"\n})
end
# Initialize a volume
#
# @param volume [String] Volume
# @return [void]
def fsinit(volume)
if volume !~ /^[0-2]:$/
raise ArgumentError, "Volume must be 0:, 1:, or 2:"
end
@sock.put(%Q{#{FSINIT} VOLUME = "#{volume}"\n})
end
# List a directory
#
# @param pathname [String] Pathname
# @param count [Fixnum] Number of entries to list
# @return [String] Directory listing
def fsdirlist(pathname, count = COUNT_MAX)
if pathname !~ /^[0-2]:/
raise ArgumentError, "Pathname must begin with 0:, 1:, or 2:"
end
listing = nil
@sock.put(%Q{#{FSDIRLIST} NAME = "#{pathname}" ENTRY=1 COUNT=#{count}\n})
if @sock.get(DEFAULT_TIMEOUT) =~ /ENTRY=1\r?\n(.*?)\f/m
listing = $1
end
listing
end
# Download a file
#
# @param pathname [String] Pathname
# @param size [Fixnum] Size of file
# @return [String] File as a string
def fsupload(pathname, size = SIZE_MAX)
if pathname !~ /^[0-2]:/
raise ArgumentError, "Pathname must begin with 0:, 1:, or 2:"
end
file = nil
@sock.put(%Q{#{FSUPLOAD} NAME = "#{pathname}" OFFSET=0 SIZE=#{size}\n})
if @sock.get(DEFAULT_TIMEOUT) =~ /SIZE=\d+\r?\n(.*)\f/m
file = $1
end
file
end
end
end