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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39beafe0ad28d4186166ddaa02fdb501c2d303f3
4
- data.tar.gz: 4069a701c1205324e86eae44e8153fd377ee1b0a
3
+ metadata.gz: ff40fb730a73ee5fe8f1ffe16cdbb9202001c46a
4
+ data.tar.gz: 460430ac661a1b4da1dcb80eb2fb107b1efa6983
5
5
  SHA512:
6
- metadata.gz: 1f97391b5831198c2528ab81200c0b4175c70f1de238ceafbd03d4e5e6809f18b3568d8873db2db649163eef3615270252036733ec535a7f05dd15511346b364
7
- data.tar.gz: b22a2355500c4cb7e7f3a9bfdb66fc7200edf70190ab05bd58baa6ab81a7aa79b6c6de13cfb13d726c154a454160882e09dd63468f7910ef378147eeaab5ed32
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], :host => config[:host], :port => PORT, :logger => log)
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
@@ -197,7 +197,15 @@ module TFTP
197
197
 
198
198
  # Basic read-write session over a 'physical' directory.
199
199
  class RWSimple < Base
200
- # @param path [String] Path to serving root directory
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"
@@ -1,4 +1,4 @@
1
1
  module TFTP
2
2
  # Current version string.
3
- VERSION = '0.3'
3
+ VERSION = '0.4'
4
4
  end
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.3'
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-23 00:00:00.000000000 Z
11
+ date: 2015-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubygems-tasks