fx-tftp 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -8
- data/bin/tftpd +17 -2
- data/lib/tftp/tftp.rb +21 -1
- data/lib/tftp/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff40fb730a73ee5fe8f1ffe16cdbb9202001c46a
|
4
|
+
data.tar.gz: 460430ac661a1b4da1dcb80eb2fb107b1efa6983
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be546342f4f560c6830af311548025b8dd1e2ef4ebb36548897e5c893bd4ceafd587090f75c03a60fca97b9dea04c746fe882ab970c68959a88fe35f018e3b2e
|
7
|
+
data.tar.gz: e6ebe1401188bbf0b98f0c4b5bf54a03f091e0addf28757fc806ffff7f09185f6f8c1af6f4f0bb22c9d47f03733eb7fe76627cebf0491cd03fe3edf72a26185f
|
data/README.md
CHANGED
@@ -16,13 +16,6 @@ The included `tftpd` executable gives you a fully-fledged read-write TFTP server
|
|
16
16
|
Suppose we want to have a TFTP server that only supports reading, but the files served should depend on the IP block the client is connecting from:
|
17
17
|
|
18
18
|
class CustomHandler < TFTP::Handler::RWSimple
|
19
|
-
def run!(tag, req, sock, src)
|
20
|
-
if req.is_a? TFTP::Packet::WRQ
|
21
|
-
sock.send(TFTP::Packet::ERROR.new(4, 'Nope').encode, 0)
|
22
|
-
sock.close
|
23
|
-
return
|
24
|
-
end
|
25
|
-
|
26
19
|
ip = src.remote_address.ip_address.split('.')
|
27
20
|
block = ip.slice(0, 3).join('-')
|
28
21
|
req.filename = File.join(block, req.filename)
|
@@ -31,7 +24,7 @@ Suppose we want to have a TFTP server that only supports reading, but the files
|
|
31
24
|
end
|
32
25
|
end
|
33
26
|
|
34
|
-
srv = TFTP::Server::Base.new(CustomHandler.new(path), opts)
|
27
|
+
srv = TFTP::Server::Base.new(CustomHandler.new(path, :no_write => true), opts)
|
35
28
|
|
36
29
|
When you combine filename inspection and `#send` and `#recv` methods working on plain `IO` objects you can easily whip up things like serving dynamically built scripts/binaries/archives based on parameters passed as the requested 'filename'.
|
37
30
|
|
@@ -43,6 +36,7 @@ When you combine filename inspection and `#send` and `#recv` methods working on
|
|
43
36
|
-d, --debug Enable debug output
|
44
37
|
-l, --log PATH Log to file
|
45
38
|
-b, --background Fork into background
|
39
|
+
-m, --mode MODE Run in R/W only mode
|
46
40
|
-h, --host HOST Bind do host
|
47
41
|
-p, --path PATH Serving root directory
|
48
42
|
|
data/bin/tftpd
CHANGED
@@ -8,7 +8,8 @@ require 'optparse'
|
|
8
8
|
require 'tftp'
|
9
9
|
|
10
10
|
config = {:path => Dir.pwd, :host => '127.0.0.1', :fork => false,
|
11
|
-
:ver => false, :loglevel => Logger::INFO, :logfile => STDOUT
|
11
|
+
:ver => false, :loglevel => Logger::INFO, :logfile => STDOUT,
|
12
|
+
:no_read => false, :no_write => false}
|
12
13
|
|
13
14
|
def die!(msg)
|
14
15
|
STDERR.puts msg
|
@@ -21,10 +22,21 @@ op = OptionParser.new do |o|
|
|
21
22
|
o.on('-d', '--debug', 'Enable debug output') { config[:loglevel] = Logger::DEBUG }
|
22
23
|
o.on('-l', '--log PATH', String, 'Log to file') {|a| config[:logfile] = a }
|
23
24
|
o.on('-b', '--background', 'Fork into background') {|a| config[:fork] = true }
|
25
|
+
o.on('-m', '--mode MODE', String, 'Run in R/W only mode') do |a|
|
26
|
+
case a.downcase[0]
|
27
|
+
when 'r'
|
28
|
+
config[:no_write] = true
|
29
|
+
when 'w'
|
30
|
+
config[:no_read] = true
|
31
|
+
else
|
32
|
+
config[:bad_mode] = true
|
33
|
+
end
|
34
|
+
end
|
24
35
|
o.on('-h', '--host HOST', String, 'Bind do host') {|a| config[:host] = a }
|
25
36
|
o.on('-p', '--path PATH', String, 'Serving root directory') {|a| config[:path] = a }
|
26
37
|
end
|
27
38
|
op.parse! or die!(op)
|
39
|
+
die!(op) if config[:bad_mode]
|
28
40
|
|
29
41
|
if config[:ver]
|
30
42
|
puts "fx-tftpd v#{TFTP::VERSION} Copyright (c) 2015, Piotr S. Staszewski"
|
@@ -45,9 +57,12 @@ if config[:fork]
|
|
45
57
|
Process.daemon(true)
|
46
58
|
end
|
47
59
|
|
60
|
+
config[:logger] = log
|
61
|
+
config[:port] = PORT
|
62
|
+
|
48
63
|
begin
|
49
64
|
log.info "Serving from and to #{config[:path]}"
|
50
|
-
srv = TFTP::Server::RWSimple.new(config[:path],
|
65
|
+
srv = TFTP::Server::RWSimple.new(config[:path], config)
|
51
66
|
srv.run!
|
52
67
|
rescue SignalException => e
|
53
68
|
puts if e.is_a? Interrupt
|
data/lib/tftp/tftp.rb
CHANGED
@@ -197,7 +197,15 @@ module TFTP
|
|
197
197
|
|
198
198
|
# Basic read-write session over a 'physical' directory.
|
199
199
|
class RWSimple < Base
|
200
|
-
#
|
200
|
+
# Initialize the handler.
|
201
|
+
#
|
202
|
+
# Options:
|
203
|
+
#
|
204
|
+
# - :no_read => deny read access if true
|
205
|
+
# - :no_write => deny write access if true
|
206
|
+
#
|
207
|
+
# @param path [String] Path to serving root directory
|
208
|
+
# @param opts [Hash] Options
|
201
209
|
def initialize(path, opts = {})
|
202
210
|
@path = path
|
203
211
|
super(opts)
|
@@ -219,6 +227,12 @@ module TFTP
|
|
219
227
|
|
220
228
|
case req
|
221
229
|
when Packet::RRQ
|
230
|
+
if @opts[:no_read]
|
231
|
+
log :info, "#{tag} Denied read request for #{req.filename}"
|
232
|
+
sock.send(Packet::ERROR.new(2, 'Access denied.').encode, 0)
|
233
|
+
sock.close
|
234
|
+
return
|
235
|
+
end
|
222
236
|
log :info, "#{tag} Read request for #{req.filename} (#{req.mode})"
|
223
237
|
unless File.exist? path
|
224
238
|
log :warn, "#{tag} File not found"
|
@@ -233,6 +247,12 @@ module TFTP
|
|
233
247
|
sock.close
|
234
248
|
io.close
|
235
249
|
when Packet::WRQ
|
250
|
+
if @opts[:no_write]
|
251
|
+
log :info, "#{tag} Denied write request for #{req.filename}"
|
252
|
+
sock.send(Packet::ERROR.new(2, 'Access denied.').encode, 0)
|
253
|
+
sock.close
|
254
|
+
return
|
255
|
+
end
|
236
256
|
log :info, "#{tag} Write request for #{req.filename} (#{req.mode})"
|
237
257
|
if File.exist? path
|
238
258
|
log :warn, "#{tag} File already exist"
|
data/lib/tftp/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fx-tftp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr S. Staszewski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubygems-tasks
|