init.lua 3.24 KB
Newer Older
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
1 2 3 4 5 6 7 8
--[[
Alpine Wall main module
Copyright (C) 2012 Kaarle Ritvanen
Licensed under the terms of GPL2
]]--

module(..., package.seeall)

9
require 'lfs'
10
require 'stringy'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
11

12
require 'awall.ipset'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
13
require 'awall.iptables'
14
require 'awall.model'
15
require 'awall.object'
16
require 'awall.policy'
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
17 18 19
require 'awall.util'


20 21
local procorder
local defrules
22 23

function loadmodules(path)
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   classmap = {}
   procorder = {}
   defrules = {}

   local function readmetadata(mod)
      for i, clsdef in ipairs(mod.classes) do
	 local path, cls = unpack(clsdef)
	 classmap[path] = cls
	 table.insert(procorder, path)
      end
      util.extend(defrules, mod.defrules)
   end

   readmetadata(model)

39 40 41
   local cdir = lfs.currentdir()
   if path then lfs.chdir(path) end

42 43 44 45
   for modfile in lfs.dir((path or '/usr/share/lua/5.1')..'/awall/modules') do
      if stringy.endswith(modfile, '.lua') then
	 local name = 'awall.modules.'..string.sub(modfile, 1, -5)
	 require(name)
46
	 readmetadata(package.loaded[name])
47
      end
48
   end
49 50

   lfs.chdir(cdir)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
51 52 53
end


54 55 56
PolicySet = policy.PolicySet


57
Config = object.class(object.Object)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
58

59
function Config:init(policyset)
60

61
   self.input = policyset:load()
62
   self.iptables = iptables.IPTables.new()
63

64
   local function expandvars(obj)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
65 66 67 68 69 70 71 72
      for k, v in pairs(obj) do
	 if type(v) == 'table' then
	    expandvars(v)

	 else
	    local visited = {}
	    local val = v

73 74 75 76
	    local pattern = '%$(%a[%w_]*)'

	    while type(val) == 'string' and string.find(val, pattern) do
	       local si, ei, name = string.find(val, pattern)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
77 78 79 80 81
		  
	       if util.contains(visited, name) then
		  error('Circular variable definition: '..name)
	       end
	       table.insert(visited, name)
82 83 84 85 86 87 88 89 90 91

	       local var = self.input.variable[name]
	       if not var then error('Invalid variable reference: '..name) end

	       if si == 1 and ei == string.len(val) then val = var
	       elseif util.contains({'number', 'string'}, type(var)) then
		  val = string.sub(val, 1, si - 1)..var..string.sub(val, ei + 1, -1)
	       else
		  error('Attempted to concatenate complex variable: '..name)
	       end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
92 93
	    end

94
	    obj[k] = val ~= '' and val or nil
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
95 96 97 98
	 end
      end
   end

99 100 101
   for k, v in pairs(self.input) do
      if k ~= 'variable' then expandvars(v) end
   end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
102 103


104
   local function insertrule(trule)
105
      local t = self.iptables.config[trule.family][trule.table][trule.chain]
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
106 107 108 109 110 111 112 113 114
      if trule.position == 'prepend' then
	 table.insert(t, 1, trule.opts)
      else
	 table.insert(t, trule.opts)
      end
   end

   local locations = {}

115 116 117 118 119
   for i, path in ipairs(procorder) do
      if self.input[path] then
	 util.map(self.input[path],
		  function(obj) return classmap[path].morph(obj, self) end)
	 table.insert(locations, self.input[path])
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
120 121 122
      end
   end

123
   for i, rule in ipairs(defrules) do insertrule(rule) end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
124 125 126 127 128 129

   for i, location in ipairs(locations) do
      for i, rule in ipairs(location) do
	 for i, trule in ipairs(rule:trules()) do insertrule(trule) end
      end
   end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
130

131
   self.ipset = ipset.IPSet.new(self.input.ipset)
132
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
133

134 135 136
function Config:dump(iptdir, ipsfile)
   self.ipset:dump(ipsfile or '/etc/ipset.d/awall')
   self.iptables:dump(iptdir or '/etc/iptables')
137
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
138

139 140 141
function Config:test()
   self.ipset:create()
   self.iptables:test()
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
142
end
143 144 145 146 147

function Config:activate()
   self:test()
   self.iptables:activate()
end