Class: TFTP::Handler::RWSimple
Overview
Basic read-write session over a ‘physical’ directory.
Instance Method Summary collapse
-
#initialize(path, opts = {}) ⇒ RWSimple
constructor
Initialize the handler.
-
#run!(tag, req, sock, src) ⇒ Object
Handle a session.
Methods inherited from Base
Constructor Details
#initialize(path, opts = {}) ⇒ RWSimple
Initialize the handler.
Options:
- :no_read => deny read access if true
- :no_write => deny write access if true
212 213 214 215 |
# File 'lib/tftp/tftp.rb', line 212 def initialize(path, opts = {}) @path = path super(opts) end |
Instance Method Details
#run!(tag, req, sock, src) ⇒ Object
Handle a session.
Has to close the socket (and any other resources). Note that the current version ‘guards’ against path traversal by a simple substitution of ‘..’ with ‘‘.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/tftp/tftp.rb', line 227 def run!(tag, req, sock, src) name = req.filename.gsub('..', '__') path = File.join(@path, name) case req when Packet::RRQ if @opts[:no_read] log :info, "#{tag} Denied read request for #{req.filename}" sock.send(Packet::ERROR.new(2, 'Access denied.').encode, 0) sock.close return end log :info, "#{tag} Read request for #{req.filename} (#{req.mode})" unless File.exist? path log :warn, "#{tag} File not found" sock.send(Packet::ERROR.new(1, 'File not found.').encode, 0) sock.close return end mode = 'r' mode += 'b' if req.mode == :octet io = File.open(path, mode) send(tag, sock, io) sock.close io.close when Packet::WRQ if @opts[:no_write] log :info, "#{tag} Denied write request for #{req.filename}" sock.send(Packet::ERROR.new(2, 'Access denied.').encode, 0) sock.close return end log :info, "#{tag} Write request for #{req.filename} (#{req.mode})" mode = 'w' mode += 'b' if req.mode == :octet io = File.open(path, mode) ok = recv(tag, sock, io) sock.close io.close unless ok log :warn, "#{tag} Removing partial file #{req.filename}" File.delete(path) end end end |