init.lua 3.25 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
Config = object.class(object.Object)
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
55

56
function Config:init(confdirs, importdirs)
57

58
   self.input = policy.PolicySet.new(confdirs, importdirs):load()
59
   self.iptables = iptables.IPTables.new()
60

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

	 else
	    local visited = {}
	    local val = v

70 71 72 73
	    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
74 75 76 77 78
		  
	       if util.contains(visited, name) then
		  error('Circular variable definition: '..name)
	       end
	       table.insert(visited, name)
79 80 81 82 83 84 85 86 87 88

	       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
89 90
	    end

91
	    obj[k] = val ~= '' and val or nil
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
92 93 94 95
	 end
      end
   end

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


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

   local locations = {}

112 113 114 115 116
   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
117 118 119
      end
   end

120
   for i, rule in ipairs(defrules) do insertrule(rule) end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
121 122 123 124 125 126

   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
127

128
   self.ipset = ipset.IPSet.new(self.input.ipset)
129
end
Kaarle Ritvanen's avatar
Kaarle Ritvanen committed
130

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

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

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