catflap 0.0.1.pre → 0.0.2.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/bin/catflap +8 -8
  2. data/lib/catflap-http.rb +32 -29
  3. data/lib/catflap.rb +19 -17
  4. metadata +7 -7
data/bin/catflap CHANGED
@@ -4,7 +4,7 @@ require 'optparse'
4
4
  require 'catflap'
5
5
 
6
6
  options = {}
7
- optparse = OptionParser.new do|opts|
7
+ optparse = OptionParser.new do |opts|
8
8
  opts.separator ""
9
9
  opts.separator "Install/Configure/Service options:"
10
10
  opts.on('-i', '--install', 'Install and initialize the catflap chain') do
@@ -14,7 +14,7 @@ optparse = OptionParser.new do|opts|
14
14
  options['uninstall'] = true
15
15
  end
16
16
  opts.on('-f', '--config-file <filepath>', String, 'Use config file to override default values') do |filepath|
17
- options['config_file'] = true
17
+ options['config_file'] = filepath
18
18
  end
19
19
  opts.on('-s', '--start-server', 'Start the web api server daemon') do
20
20
  options['start_server'] = true
@@ -53,18 +53,18 @@ optparse = OptionParser.new do|opts|
53
53
  end
54
54
  end.parse! ARGV
55
55
 
56
+ cf = Catflap.new options['config_file']
56
57
  unless options['start_server']
57
- cf = Catflap.new(options['config_file'])
58
58
  cf.purge_rules! if options['purge']
59
59
  cf.install_rules! if options['install']
60
60
  cf.uninstall_rules! if options['uninstall']
61
- cf.add_address!(options['add']) if options['add']
62
- cf.delete_address!(options['del']) if options['del']
63
- cf.add_addresses_from_file!(options['filepath']) if options['filepath']
64
- cf.check_address(options['check']) if options['check']
61
+ cf.add_address! options['add'] if options['add']
62
+ cf.delete_address! options['del'] if options['del']
63
+ cf.add_addresses_from_file! options['filepath'] if options['filepath']
64
+ cf.check_address options['check'] if options['check']
65
65
  cf.list_rules if options['list']
66
66
  else
67
67
  require 'catflap-http'
68
- CatflapWebserver::start_server(options['config_file'])
68
+ CatflapWebserver::start_server cf
69
69
  end
70
70
 
data/lib/catflap-http.rb CHANGED
@@ -6,7 +6,7 @@ include WEBrick
6
6
 
7
7
  module CatflapWebserver
8
8
 
9
- def self.generate_server(port)
9
+ def self.generate_server port
10
10
  config = {:Port => port}
11
11
  server = HTTPServer.new(config)
12
12
  yield server if block_given?
@@ -16,43 +16,49 @@ module CatflapWebserver
16
16
  server.start
17
17
  end
18
18
 
19
- def self.start_server(port = 4777)
20
- generate_server(port) do |server|
21
- server.mount('/', Servlet)
19
+ def self.start_server cf
20
+ generate_server cf.port do |server|
21
+ server.mount '/', Servlet, cf
22
22
  end
23
23
  end
24
24
 
25
25
  class Servlet < HTTPServlet::AbstractServlet
26
- def do_GET(req,resp)
26
+
27
+ def initialize server, cf
28
+ super server
29
+ @cf = cf
30
+ end
31
+
32
+ def do_GET req, resp
27
33
  # Split the path into piece
28
34
  path = req.path[1..-1].split('/')
29
35
  raise HTTPStatus::OK if path[0] == 'favicon.ico'
30
- response_class = CatflapRestService.const_get("Service")
36
+ response_class = CatflapRestService.const_get 'Service'
31
37
 
32
- if response_class and response_class.is_a?(Class)
38
+ if response_class and response_class.is_a? Class
33
39
  # There was a method given
34
40
  if path[0]
35
41
  response_method = path[0].to_sym
36
42
  # Make sure the method exists in the class
37
- raise HTTPStatus::NotFound if !response_class.respond_to?(response_method)
43
+ raise HTTPStatus::NotFound if !response_class.respond_to? response_method
38
44
 
39
45
  if path[0] == "enter"
40
- url = response_class.send(response_method, req, resp)
41
- resp.set_redirect(HTTPStatus::Redirect, url)
46
+ url = response_class.send response_method, req, resp, @cf
47
+ resp.set_redirect HTTPStatus::Redirect, url
42
48
  end
43
49
 
44
50
  # Remaining path segments get passed in as arguments to the method
45
51
  if path.length > 1
46
- resp.body = response_class.send(response_method, req, resp, path[1..-1])
52
+ resp.body = response_class.send response_method, req, resp, @cf, path[1..-1]
47
53
  else
48
- resp.body = response_class.send(response_method, req, resp)
54
+ resp.body = response_class.send response_method, req, resp, @cf
49
55
  end
50
56
  raise HTTPStatus::OK
51
57
 
52
58
  # No method was given, so check for an "index" method instead
53
59
  else
54
- raise HTTPStatus::NotFound if !response_class.respond_to?(:index)
55
- resp.body = response_class.send(:index)
60
+ raise HTTPStatus::NotFound if !response_class.respond_to? :index
61
+ resp.body = response_class.send :index
56
62
  raise HTTPStatus::OK
57
63
  end
58
64
  else
@@ -65,43 +71,40 @@ end
65
71
  module CatflapRestService
66
72
  class Service
67
73
 
68
- @@cf = Catflap.new
69
- @@cf.dports = '80,8080,443'
70
-
71
- def self.index()
74
+ def self.index
72
75
  return "hello world"
73
76
  end
74
77
 
75
- def self.enter(req, resp)
78
+ def self.enter req, resp, cf
76
79
  ip = req.peeraddr.pop
77
80
  host = req.addr[2]
78
- @@cf.add_address!(ip) unless @@cf.check_address(ip)
81
+ cf.add_address! ip unless cf.check_address ip
79
82
  return "http://" << host << ":80"
80
83
  end
81
84
 
82
- def self.add(req, resp, args)
85
+ def self.add req, resp, cf, args
83
86
  ip = args[0]
84
- unless @@cf.check_address(ip)
85
- @@cf.add_address!(ip)
87
+ unless cf.check_address ip
88
+ cf.add_address! ip
86
89
  return "#{ip} has been granted access"
87
90
  else
88
91
  return "#{ip} already has access"
89
92
  end
90
93
  end
91
94
 
92
- def self.remove(req, resp, args)
95
+ def self.remove req, resp, cf, args
93
96
  ip = args[0]
94
- @@cf.delete_address!(ip)
97
+ cf.delete_address! ip
95
98
  return "Access granted to #{ip} has been removed"
96
99
  end
97
100
 
98
- def self.check(req, resp, args)
101
+ def self.check req, resp, cf, args
99
102
  ip = args[0]
100
103
 
101
- if @@cf.check_address(ip)
102
- return "#{ip} has access to ports: #{@@cf.dports}"
104
+ if cf.check_address ip
105
+ return "#{ip} has access to ports: #{cf.dports}"
103
106
  else
104
- return "#{ip} does not have access to ports: #{@@cf.dports}"
107
+ return "#{ip} does not have access to ports: #{cf.dports}"
105
108
  end
106
109
  end
107
110
  end
data/lib/catflap.rb CHANGED
@@ -2,12 +2,14 @@ require 'yaml'
2
2
 
3
3
  class Catflap
4
4
 
5
- attr_accessor :chain, :dports, :print, :noop, :log_rejected
5
+ attr_accessor :config, :chain, :port, :dports, :print, :noop, :log_rejected
6
6
 
7
- def initialize(config_file = nil)
8
- @config = YAML.load_file(config_file) if config_file and File.exists?(config_file)
9
- @chain = (@config['rules']['chain']) ? @config['rules']['chain'] : "catflap-accept"
10
- @dports = (@config['rules']['dports']) ? @config['rules']['dports'] : "80,443"
7
+ def initialize config_file
8
+ @config = {}
9
+ @config = YAML.load_file config_file if File.readable? config_file
10
+ @port = @config['server']['port'] || 4777
11
+ @chain = @config['rules']['chain'] || 'catflap-accept'
12
+ @dports = @config['rules']['dports'] || '80,443'
11
13
  @print = false
12
14
  @noop = false
13
15
  @log_rejected = true
@@ -19,7 +21,7 @@ class Catflap
19
21
  output << "iptables -A INPUT -p tcp -m multiport --dports #{@dports} -j #{@chain}\n" # Jump from INPUT chain to the catflap chain
20
22
  output << "iptables -A INPUT -p tcp -m multiport --dports #{@dports} -j LOG\n" if @log_rejected # Log any rejected packets to /var/log/messages
21
23
  output << "iptables -A INPUT -p tcp -m multiport --dports #{@dports} -j DROP\n" # Drop any other packets to the ports on the INPUT chain
22
- execute!(output)
24
+ execute! output
23
25
  end
24
26
 
25
27
  def uninstall_rules!
@@ -28,46 +30,46 @@ class Catflap
28
30
  output << "iptables -X #{@chain}\n" # Remove the catflap chain
29
31
  output << "iptables -D INPUT -p tcp -m multiport --dports #{@dports} -j LOG\n" # Remove the logging rule
30
32
  output << "iptables -D INPUT -p tcp -m multiport --dports #{@dports} -j DROP\n" # Remove the packet dropping rule
31
- execute!(output)
33
+ execute! output
32
34
  end
33
35
 
34
36
  def purge_rules!
35
37
  output = "iptables -F #{@chain}"
36
- execute!(output)
38
+ execute! output
37
39
  end
38
40
 
39
41
  def list_rules
40
42
  system "iptables -S #{@chain}"
41
43
  end
42
44
 
43
- def check_address(ip)
45
+ def check_address ip
44
46
  return system "iptables -C #{@chain} -s #{ip} -p tcp -m multiport --dports #{@dports} -j ACCEPT\n"
45
47
  end
46
48
 
47
- def add_address!(ip)
49
+ def add_address! ip
48
50
  output = "iptables -I #{@chain} 1 -s #{ip} -p tcp -m multiport --dports #{@dports} -j ACCEPT\n"
49
- execute!(output)
51
+ execute! output
50
52
  end
51
53
 
52
- def delete_address!(ip)
54
+ def delete_address! ip
53
55
  output = "iptables -D #{@chain} -s #{ip} -p tcp -m multiport --dports #{@dports} -j ACCEPT\n"
54
- execute!(output)
56
+ execute! output
55
57
  end
56
58
 
57
- def add_addresses_from_file!(filepath)
58
- if File.readable?(filepath)
59
+ def add_addresses_from_file! filepath
60
+ if File.readable? filepath
59
61
  output = ""
60
62
  File.open(filepath, "r").each_line do |ip|
61
63
  output << "iptables -I #{@chain} 1 -s #{ip.chomp} -p tcp -m multiport --dports #{@dports} -j ACCEPT\n"
62
64
  end
63
- execute!(output)
65
+ execute! output
64
66
  else
65
67
  puts "The file #{filepath} is not readable!"
66
68
  exit 1
67
69
  end
68
70
  end
69
71
 
70
- def execute!(output)
72
+ def execute! output
71
73
  if @print then puts output end
72
74
  system output unless @noop
73
75
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: catflap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre
4
+ version: 0.0.2.pre
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -11,8 +11,8 @@ bindir: bin
11
11
  cert_chain: []
12
12
  date: 2013-12-01 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: A simple solution for service access (e.g. port 80 on webserver) where
15
- a more robust and secure VPN solution is not available
14
+ description: A simple solution to provide on-demand service access (e.g. port 80 on
15
+ webserver), where a more robust and secure VPN solution is not available.
16
16
  email: nyk@demotix.com
17
17
  executables:
18
18
  - catflap
@@ -22,7 +22,7 @@ files:
22
22
  - lib/catflap.rb
23
23
  - lib/catflap-http.rb
24
24
  - bin/catflap
25
- homepage: http://rubygems.org/gems/catflap
25
+ homepage: https://github.com/nyk/catflap
26
26
  licenses:
27
27
  - MIT
28
28
  post_install_message:
@@ -42,11 +42,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.3.1
44
44
  requirements:
45
- - NetFilters (iptables) installed and working
45
+ - NetFilters (iptables) installed and working.
46
46
  rubyforge_project:
47
47
  rubygems_version: 1.8.11
48
48
  signing_key:
49
49
  specification_version: 3
50
- summary: Manage NetFilter-based rules to grant port access on demand via commandline
51
- or REST API requests
50
+ summary: Manage NetFilter-based rules to grant port access on-demand via commandline
51
+ or REST API requests.
52
52
  test_files: []