CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/proto/pjl/client.rb
Views: 11702
1
# -*- coding: binary -*-
2
3
# https://en.wikipedia.org/wiki/Printer_Job_Language
4
# See external links for PJL spec
5
6
module Rex::Proto::PJL
7
class Client
8
9
def initialize(sock)
10
@sock = sock
11
end
12
13
# Begin a PJL job
14
#
15
# @return [void]
16
def begin_job
17
@sock.put("#{UEL}#{PREFIX}\n")
18
end
19
20
# End a PJL job
21
#
22
# @return [void]
23
def end_job
24
@sock.put(UEL)
25
end
26
27
# Send an INFO request and read the response
28
#
29
# @param category [String] INFO category
30
# @return [String] INFO response
31
def info(category)
32
categories = {
33
:id => Info::ID,
34
:status => Info::STATUS,
35
:variables => Info::VARIABLES,
36
:filesys => Info::FILESYS
37
}
38
39
unless categories.has_key?(category)
40
raise ArgumentError, "Unknown INFO category"
41
end
42
43
@sock.put("#{categories[category]}\n")
44
@sock.get(DEFAULT_TIMEOUT)
45
end
46
47
# Get version information
48
#
49
# @return [String] Version information
50
def info_id
51
id = nil
52
53
if info(:id) =~ /"(.*?)"/m
54
id = $1
55
end
56
57
id
58
end
59
60
# Get environment variables
61
#
62
# @return [String] Environment variables
63
def info_variables
64
env_vars = nil
65
66
if info(:variables) =~ /#{Info::VARIABLES}\r?\n(.*?)\f/m
67
env_vars = $1
68
end
69
70
env_vars
71
end
72
73
# List volumes
74
#
75
# @return [String] Volume listing
76
def info_filesys
77
filesys = nil
78
79
if info(:filesys) =~ /\[\d+ TABLE\]\r?\n(.*?)\f/m
80
filesys = $1
81
end
82
83
filesys
84
end
85
86
# Get the ready message
87
#
88
# @return [String] Ready message
89
def get_rdymsg
90
rdymsg = nil
91
92
if info(:status) =~ /DISPLAY="(.*?)"/m
93
rdymsg = $1
94
end
95
96
rdymsg
97
end
98
99
# Set the ready message
100
#
101
# @param message [String] Ready message
102
# @return [void]
103
def set_rdymsg(message)
104
@sock.put(%Q{#{RDYMSG} DISPLAY = "#{message}"\n})
105
end
106
107
# Initialize a volume
108
#
109
# @param volume [String] Volume
110
# @return [void]
111
def fsinit(volume)
112
if volume !~ /^[0-2]:$/
113
raise ArgumentError, "Volume must be 0:, 1:, or 2:"
114
end
115
116
@sock.put(%Q{#{FSINIT} VOLUME = "#{volume}"\n})
117
end
118
119
# Query a file
120
#
121
# @param path [String] Remote path
122
# @return [Boolean] True if file exists
123
def fsquery(path)
124
if path !~ /^[0-2]:/
125
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
126
end
127
128
file = false
129
130
@sock.put(%Q{#{FSQUERY} NAME = "#{path}"\n})
131
132
if @sock.get(DEFAULT_TIMEOUT) =~ /TYPE=(FILE|DIR)/m
133
file = true
134
end
135
136
file
137
end
138
139
# List a directory
140
#
141
# @param path [String] Remote path
142
# @param count [Integer] Number of entries to list
143
# @return [String] Directory listing
144
def fsdirlist(path, count = COUNT_MAX)
145
if path !~ /^[0-2]:/
146
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
147
end
148
149
listing = nil
150
151
@sock.put(%Q{#{FSDIRLIST} NAME = "#{path}" ENTRY=1 COUNT=#{count}\n})
152
153
if @sock.get(DEFAULT_TIMEOUT) =~ /ENTRY=1\r?\n(.*?)\f/m
154
listing = $1
155
end
156
157
listing
158
end
159
160
# Download a file
161
#
162
# @param path [String] Remote path
163
# @return [String] File as a string
164
def fsupload(path)
165
if path !~ /^[0-2]:/
166
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
167
end
168
169
file = nil
170
171
@sock.put(%Q{#{FSUPLOAD} NAME = "#{path}" OFFSET=0 SIZE=#{SIZE_MAX}\n})
172
173
if @sock.get(DEFAULT_TIMEOUT) =~ /SIZE=\d+\r?\n(.*)\f/m
174
file = $1
175
end
176
177
file
178
end
179
180
# Upload a file or write string data to remote path
181
#
182
# @param data_or_lpath [String] data or local path
183
# @param rpath [String] Remote path
184
# @param is_file [Boolean] True if data_or_lpath is a local file path
185
# @return [Boolean] True if the file was uploaded
186
def fsdownload(data_or_lpath, rpath, is_file: true)
187
if rpath !~ /^[0-2]:/
188
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
189
end
190
191
file = is_file ? File.read(data_or_lpath) : data_or_lpath
192
193
@sock.put(
194
%Q{#{FSDOWNLOAD} FORMAT:BINARY SIZE=#{file.length} NAME = "#{rpath}"\n}
195
)
196
197
@sock.put(file)
198
@sock.put(UEL)
199
200
fsquery(rpath)
201
end
202
203
# Delete a file
204
#
205
# @param path [String] Remote path
206
# @return [Boolean] True if the file was deleted
207
def fsdelete(path)
208
if path !~ /^[0-2]:/
209
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
210
end
211
212
@sock.put(%Q{#{FSDELETE} NAME = "#{path}"\n})
213
214
!fsquery(path)
215
end
216
217
end
218
end
219
220