diff options
-rw-r--r-- | shorewall-config-html.lsp | 12 | ||||
-rw-r--r-- | shorewall-controller.lua | 179 | ||||
-rw-r--r-- | shorewall-html.lsp | 12 | ||||
-rw-r--r-- | shorewall-model.lua | 264 | ||||
-rw-r--r-- | shorewall.menu | 2 |
5 files changed, 301 insertions, 168 deletions
diff --git a/shorewall-config-html.lsp b/shorewall-config-html.lsp index db97aa5..3f8eb8d 100644 --- a/shorewall-config-html.lsp +++ b/shorewall-config-html.lsp @@ -60,7 +60,7 @@ displayinfo(myform,tags,"viewonly") <H3>Parameters</H3> <DL> <? -local tags = { "params_list", "params_list_cmd", } +local tags = { "params", "params_cmd", } displayinfo(myform,tags) ?> </DL> @@ -68,7 +68,7 @@ displayinfo(myform,tags) <H3>Interfaces</H3> <DL> <? -local tags = { "interfaces_list", "interfaces_list_cmd", } +local tags = { "interfaces", "interfaces_cmd", } displayinfo(myform,tags) ?> </DL> @@ -77,15 +77,15 @@ displayinfo(myform,tags) <H3>Defince zones</H3> <DL> <? -local tags = { "zones_list", "zones_list_cmd", } +local tags = { "zones", "zones_cmd", } displayinfo(myform,tags) ?> </DL> -<h3>Default policies</h3> +<h3>Default policy</h3> <DL> <? -local tags = { "policies_list", "policies_list_cmd",} +local tags = { "policy", "policy_cmd",} displayinfo(myform,tags) ?> </DL> @@ -93,7 +93,7 @@ displayinfo(myform,tags) <h3>Rules</h3> <DL> <? -local tags = { "rules_list", "rules_list_cmd",} +local tags = { "rules", "rules_cmd",} displayinfo(myform,tags) ?> </DL> diff --git a/shorewall-controller.lua b/shorewall-controller.lua index b358e67..dd64ae2 100644 --- a/shorewall-controller.lua +++ b/shorewall-controller.lua @@ -61,29 +61,38 @@ end -- ################################################################################ -- PUBLIC FUNCTIONS -function save_records(self) - return { - edit={}, - option={ script=ENV["SCRIPT_NAME"], - prefix=self.conf.prefix, - controller = self.conf.controller, - action = "save_records", - link = ENV["SCRIPT_NAME"] .. self.conf.prefix .. self.conf.controller, }, - clientdata=self.clientdata, - } -end - -function edit_records(self,types,record) +function edit_records(self,types,record,errormessage) local recorddetails = {} local edit = {} local config=self.model:getconfig() + -- Split the record into a table local recordtable = {} for word in string.gmatch(record, "%S+") do table.insert(recordtable, word) end + -- Save info on how the original record looked like + edit.orgrecord = cfe({ + name="orgrecord", + label="Original record", + value=record, + type="hidden", + }) + + -- Specify a actiontype (this is then used when we make changes) + edit.actiontype = cfe({ + name="actiontype", + label="Type of action [add|delete|modify]", + type="hidden", + }) + if (record == newrecordtxt) then + edit.actiontype.value = "add" + else + edit.actiontype.value = "modify" + end + if (types == "params") then table.insert(edit, cfe({ name=1, @@ -97,8 +106,7 @@ function edit_records(self,types,record) -- Display save button local cmdsave = displaycmdsave() --- cmdsave.disabled="yes" -- DEBUGGING --- cmdsave.descr="This button is not yet programmed to work" -- DEBUGGING + cmdsave.errtxt=errormessage or "" -- Display delete button cmddelete = cfe({ name="cmddelete", @@ -106,9 +114,6 @@ function edit_records(self,types,record) value="Delete", type="submit", }) - cmddelete.disabled="yes" -- DEBUGGING - cmddelete.descr="This button is not yet programmed to work" -- DEBUGGING - if (types == "interfaces") then @@ -134,7 +139,7 @@ function edit_records(self,types,record) edit[fieldnum]["value"] = "-" end table.insert(edit[fieldnum]["option"], "-") - for k,v in pairs(config.zones_list.option or {}) do + for k,v in pairs(config.zones.option or {}) do table.insert(edit[fieldnum]["option"], string.match(v, "^%s*(%S*)")) end -- IF the value is not one of the existing options, then warn and add this option. @@ -456,7 +461,7 @@ function edit_records(self,types,record) end -- Add a hidden input where we define which config-file should be modified - edit.file = cfe({ + edit.filename = cfe({ label="File to edit", name="filename", value=types, @@ -469,7 +474,7 @@ function edit_records(self,types,record) option={ script=ENV["SCRIPT_NAME"], prefix=self.conf.prefix, controller = self.conf.controller, - action = "save_records", + action = "config", link = ENV["SCRIPT_NAME"] .. self.conf.prefix .. self.conf.controller, }, cmdsave=cmdsave, cmddelete=cmddelete, @@ -482,114 +487,163 @@ function status(self) end function config(self) + + -- If we made some changes to a recods... then proceed with the modification + local savesuccess, configmessage + if (self.clientdata.cmdsave) or (self.clientdata.cmddelete) then + + -- Check to see that user has entered accepted values + local inputfields = {} + local invalidinputfields + if (self.clientdata) then + for i=1,#self.clientdata do + table.insert(inputfields, self.clientdata[i]) + if (self.clientdata[i+1]) and (#self.clientdata[i+1] > 0 ) and (#self.clientdata[i] == 0) then + configmessage = cfe({errtxt="Skipped fileds should contain '-'"}) + end + end + end + + -- What are we going to do with the record... + local modify_actiontype = self.clientdata.actiontype or "unknown" + if (self.clientdata.cmddelete) then + modify_actiontype = "delete" + end + + + + if not ((configmessage) and (#configmessage.errtxt > 0)) then + --Actually change the values + savesuccess, configmessage = self.model:modify_config(modify_actiontype, + self.clientdata.filename, + inputfields, + self.clientdata.orgrecord) + end + + end + -- If we previously made some changes, report this to user + if ((self.clientdata.cmdsave) or (self.clientdata.cmddelete)) and not (savesuccess) then + self.conf.action = "edit_records" + self.conf.type = "redir" + return edit_records(self,self.clientdata.filename, self.clientdata.orgrecord,tostring((configmessage.errtxt or ""))) + end + local config=self.model:getconfig() local status=self.model.getstatus() -- Add a [New] record to the options - table.insert(config.interfaces_list.option, newrecordtxt) - table.insert(config.zones_list.option, newrecordtxt) - table.insert(config.policies_list.option, newrecordtxt) - table.insert(config.rules_list.option, newrecordtxt) - table.insert(config.params_list.option, newrecordtxt) + table.insert(config.interfaces.option, newrecordtxt) + table.insert(config.zones.option, newrecordtxt) + table.insert(config.policy.option, newrecordtxt) + table.insert(config.rules.option, newrecordtxt) + table.insert(config.params.option, newrecordtxt) -- Add button - config.params_list_cmd = cfe ({ - name="params_list_cmd", + config.params_cmd = cfe ({ + name="params_cmd", label="Edit above record", value="Edit", type="submit", -- disabled="yes", }) - config.params_list_cmd.descr="Mark a item in above list before pressing [" .. config.params_list_cmd.value .. "]" + config.params_cmd.descr="Mark a item in above list before pressing [" .. config.params_cmd.value .. "]" -- Add button - config.interfaces_list_cmd = cfe ({ - name="interfaces_list_cmd", + config.interfaces_cmd = cfe ({ + name="interfaces_cmd", label="Edit above record", value="Edit", type="submit", -- disabled="yes", }) - config.interfaces_list_cmd.descr="Mark a item in above list before pressing [" .. config.interfaces_list_cmd.value .. "]" + config.interfaces_cmd.descr="Mark a item in above list before pressing [" .. config.interfaces_cmd.value .. "]" -- Add button - config.zones_list_cmd = cfe ({ - name="zones_list_cmd", + config.zones_cmd = cfe ({ + name="zones_cmd", label="Edit above record", value="Edit", type="submit", -- disabled="yes", }) - config.zones_list_cmd.descr="Mark a item in above list before pressing [" .. config.zones_list_cmd.value .. "]" + config.zones_cmd.descr="Mark a item in above list before pressing [" .. config.zones_cmd.value .. "]" -- Add button - config.policies_list_cmd = cfe ({ - name="policies_list_cmd", + config.policy_cmd = cfe ({ + name="policy_cmd", label="Edit above record", value="Edit", type="submit", -- disabled="yes", }) - config.policies_list_cmd.descr="Mark a item in above list before pressing [" .. config.policies_list_cmd.value .. "]" + config.policy_cmd.descr="Mark a item in above list before pressing [" .. config.policy_cmd.value .. "]" -- Add button - config.rules_list_cmd = cfe ({ - name="rules_list_cmd", + config.rules_cmd = cfe ({ + name="rules_cmd", label="Edit above record", value="Edit", type="submit", -- disabled="yes", -- errtxt="This button is not yet programmed!", }) - config.rules_list_cmd.descr="Mark a item in above list before pressing [" .. config.rules_list_cmd.value .. "]" + config.rules_cmd.descr="Mark a item in above list before pressing [" .. config.rules_cmd.value .. "]" -- Management buttons -- Display management buttons local management = displaycmdmanagement(disablestart,disablestop,disablerestart) -- Redirect if button is pressed - if (self.clientdata.params_list_cmd) and (self.clientdata.params_list) then + if (self.clientdata.params_cmd) and (self.clientdata.params) then self.conf.action = "edit_records" self.conf.type = "redir" - return edit_records(self,"params", self.clientdata.params_list) - elseif (self.clientdata.params_list_cmd) and not (self.clientdata.params_list) then - config.params_list_cmd.errtxt = "You need to specify a record to edit!" + return edit_records(self,"params", self.clientdata.params) + elseif (self.clientdata.params_cmd) and not (self.clientdata.params) then + config.params_cmd.errtxt = "You need to specify a record to edit!" end -- Redirect if button is pressed - if (self.clientdata.interfaces_list_cmd) and (self.clientdata.interfaces_list) then + if (self.clientdata.interfaces_cmd) and (self.clientdata.interfaces) then self.conf.action = "edit_records" self.conf.type = "redir" - return edit_records(self,"interfaces", self.clientdata.interfaces_list) - elseif (self.clientdata.interfaces_list_cmd) and not (self.clientdata.interfaces_list) then - config.interfaces_list_cmd.errtxt = "You need to specify a record to edit!" + return edit_records(self,"interfaces", self.clientdata.interfaces) + elseif (self.clientdata.interfaces_cmd) and not (self.clientdata.interfaces) then + config.interfaces_cmd.errtxt = "You need to specify a record to edit!" end -- Redirect if button is pressed - if (self.clientdata.zones_list_cmd) and (self.clientdata.zones_list) then + if (self.clientdata.zones_cmd) and (self.clientdata.zones) then self.conf.action = "edit_records" self.conf.type = "redir" - return edit_records(self,"zones", self.clientdata.zones_list) - elseif (self.clientdata.zones_list_cmd) and not (self.clientdata.zones_list) then - config.zones_list_cmd.errtxt = "You need to specify a record to edit!" + return edit_records(self,"zones", self.clientdata.zones) + elseif (self.clientdata.zones_cmd) and not (self.clientdata.zones) then + config.zones_cmd.errtxt = "You need to specify a record to edit!" end -- Redirect if button is pressed - if (self.clientdata.policies_list_cmd) and (self.clientdata.policies_list) then + if (self.clientdata.policy_cmd) and (self.clientdata.policy) then self.conf.action = "edit_records" self.conf.type = "redir" - return edit_records(self,"policy", self.clientdata.policies_list) - elseif (self.clientdata.policies_list_cmd) and not (self.clientdata.policies_list) then - config.policies_list_cmd.errtxt = "You need to specify a record to edit!" + return edit_records(self,"policy", self.clientdata.policy) + elseif (self.clientdata.policy_cmd) and not (self.clientdata.policy) then + config.policy_cmd.errtxt = "You need to specify a record to edit!" end -- Redirect if button is pressed - if (self.clientdata.rules_list_cmd) and (self.clientdata.rules_list) then + if (self.clientdata.rules_cmd) and (self.clientdata.rules) then self.conf.action = "edit_records" self.conf.type = "redir" - return edit_records(self,"rules", self.clientdata.rules_list) - elseif (self.clientdata.rules_list_cmd) and not (self.clientdata.rules_list) then - config.rules_list_cmd.errtxt = "You need to specify a record to edit!" + return edit_records(self,"rules", self.clientdata.rules) + elseif (self.clientdata.rules_cmd) and not (self.clientdata.rules) then + config.rules_cmd.errtxt = "You need to specify a record to edit!" + end + + -- If we previously made some changes, report this to user + if ((self.clientdata.cmdsave) or (self.clientdata.cmddelete)) and (savesuccess) and (configmessage) and (configmessage.descr) then + local reporttobutton = self.clientdata.filename .. "_cmd" + if (config[reporttobutton]) then + config[reporttobutton]["descr"] = tostring(configmessage.descr) + end end return { @@ -602,7 +656,8 @@ function config(self) action = "expert", link = ENV["SCRIPT_NAME"] .. self.conf.prefix .. self.conf.controller, }, clientdata=clientdata, - + savesuccess=savesuccess, + configmessage=configmessage, } end diff --git a/shorewall-html.lsp b/shorewall-html.lsp index 1672808..7f99407 100644 --- a/shorewall-html.lsp +++ b/shorewall-html.lsp @@ -78,7 +78,15 @@ displayinfo(myform,tags) ?> <? -- Add the field that holds the filename -local myform = form.edit.file +local myform = form.edit.filename +if (type(myform) == "table") then + io.write(html.form[myform.type](myform)) +end +local myform = form.edit.orgrecord +if (type(myform) == "table") then + io.write(html.form[myform.type](myform)) +end +local myform = form.edit.actiontype if (type(myform) == "table") then io.write(html.form[myform.type](myform)) end @@ -89,7 +97,7 @@ end </form> <? ----[[ DEBUG INFORMATION +--[[ DEBUG INFORMATION io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") io.write(html.cfe_unpack(form)) io.write("</span>") diff --git a/shorewall-model.lua b/shorewall-model.lua index 0375b06..e9ca529 100644 --- a/shorewall-model.lua +++ b/shorewall-model.lua @@ -48,9 +48,160 @@ local function read_config(file) end return output end + +---[[ +local function addremove_config( addremove, file, value, orgvalue ) + filepath = baseurl .. file + local cmdoutput + + -- Check if we are about to change a valid filename + local isvalidfile + for k,v in pairs(getfilelist()) do + isvalidfile = true + if (v.value == filepath) then + break + end + isvalidfile = false + end + if not (fs.is_file(filepath)) or not (isvalidfile) then + return false, cfe({ + name="model:addremove_config()", + errtxt="'" .. filepath .. "' is not a valid file!", + }) + end + + if not (type(value) == "table") then + return false, cfe({ + name="model:addremove_config()", + errtxt="Value should come as an array!", + }) + end + + local filecontentarray = fs.read_file_as_array(filepath) + + if (addremove == "delete" ) then + local modifyrow + local orgrecordtable = {} + for word in string.gmatch(orgvalue, "%S+") do + table.insert(orgrecordtable, word) + end + for i=1, #filecontentarray do + local recordtable = {} + for word in string.gmatch(filecontentarray[i], "%S+") do + table.insert(recordtable, word) + end + + if (table.concat(recordtable) == table.concat(orgrecordtable)) then + modifyrow = i + end + end + + if (tonumber(modifyrow)) then + table.remove(filecontentarray, modifyrow) + fs.write_file(filepath, table.concat(filecontentarray, "\n")) + return true, cfe({ + name="model:addremove_config()", + descr="* Record was successfully deleted!", + }) + else + return false, cfe({ + name="model:addremove_config()", + errtxt="Record was not deleted!" .. +"<BR>orgvalue:" .. tostring(orgvalue) .. +"<BR>modifyrow:" .. tostring(modifyrow) .. +"<BR>orgrecordtable:" .. table.concat(orgrecordtable, ";") .. +"<BR>file:" .. tostring(file) .. +"<BR>filecontentarray:" .. table.concat(filecontentarray, ";") .. +"" + , + }) + end + + elseif (addremove == "add" ) then + --Check if such record already exists + for k,v in pairs(filecontentarray) do + if not string.find ( v, "^[;#].*" ) then + local recordtable = {} + for word in string.gmatch(v, "%S+") do + table.insert(recordtable, word) + end + if (table.concat(recordtable) == table.concat(value)) then + return false, cfe({ + name="model:addremove_config()", + errtxt="The config already holds this kind of config!", + }) + end + end + end + + table.insert(filecontentarray, (#filecontentarray), table.concat(value, "\t")) + fs.write_file(filepath, table.concat(filecontentarray, "\n")) + return true, cfe({ + name="model:addremove_config()", + descr="* Record was successfully added!", + }) + + elseif (addremove == "modify" ) then + local modifyrow + local orgrecordtable = {} + for word in string.gmatch(orgvalue, "%S+") do + table.insert(orgrecordtable, word) + end + for i=1, #filecontentarray do + local recordtable = {} + for word in string.gmatch(filecontentarray[i], "%S+") do + table.insert(recordtable, word) + end + + if (table.concat(recordtable) == table.concat(orgrecordtable)) then + modifyrow = i + end + end + + if (tonumber(modifyrow)) then + table.remove(filecontentarray, modifyrow) + table.insert(filecontentarray, modifyrow, table.concat(value, "\t")) + fs.write_file(filepath, table.concat(filecontentarray, "\n")) + return true, cfe({ + name="model:addremove_config()", + descr="* Record was successfully modified!", + }) + else + return false, cfe({ + name="model:addremove_config()", + errtxt="Record was not modified!".. +"<BR>orgvalue:" .. tostring(orgvalue) .. +"<BR>modifyrow:" .. tostring(modifyrow) .. +"<BR>orgrecordtable:" .. table.concat(orgrecordtable, ";") .. +"<BR>file:" .. tostring(file) .. +"<BR>filecontentarray:" .. table.concat(filecontentarray, ";") .. +"" +, + }) + end + + else + return false, cfe({ + name="model:addremove_config()", + errtxt="Wrong usage of this function! Available options are [add|delete|modify]. You chose '" .. addremove .. "'", + }) + end + + return false, cfe({ + name="model:addremove_config()", + errtxt="Something went wrong!", + debug=value, + }) +end +--]] + -- ################################################################################ -- PUBLIC FUNCTIONS +function modify_config(self, addremove, file, value, orgvalue ) + return addremove_config(addremove, file, value, orgvalue ) +end + -- action should be a CFE function startstop_service ( self, action ) local cmd = action.value @@ -65,45 +216,45 @@ end function getconfig() local config = {} - config.params_list = cfe({ - name = "params_list", + config.params = cfe({ + name = "params", label="List of parameters", type="select", option=read_config("params"), }) - config.params_list.size=#config.params_list.option + 1 + config.params.size=#config.params.option + 1 - config.interfaces_list = cfe({ - name = "interfaces_list", + config.interfaces = cfe({ + name = "interfaces", label="List of interfaces", type="select", option=read_config("interfaces"), }) - config.interfaces_list.size=#config.interfaces_list.option + 1 + config.interfaces.size=#config.interfaces.option + 1 - config.zones_list = cfe({ - name = "zones_list", + config.zones = cfe({ + name = "zones", label="List of zones", type="select", option=read_config("zones"), }) - config.zones_list.size=#config.zones_list.option + 1 + config.zones.size=#config.zones.option + 1 - config.policies_list = cfe({ - name = "policies_list", - label="List of policies", + config.policy = cfe({ + name = "policy", + label="List of policy", type="select", option=read_config("policy"), }) - config.policies_list.size=#config.policies_list.option + 1 + config.policy.size=#config.policy.option + 1 - config.rules_list = cfe({ - name = "rules_list", + config.rules = cfe({ + name = "rules", label="List of rules", type="select", option=read_config("rules"), }) - config.rules_list.size=#config.rules_list.option + 1 + config.rules.size=#config.rules.option + 1 return config @@ -228,87 +379,6 @@ function getfiledetails(self,search) return file end - --- IMPORTANT! This function is a exception! It's not fed with CFE's --- Parameter should be one of the ones defined in the variable 'variabletranslator'. --- value should be whatever the new value should be. -function setconfigs(self,parameter,value) - -- Set variables - local variable = "SYSLOGD_OPTS" - local variabletranslator = ({ - logfile = "-O", - loglevel = "-l", - smallerlogs = "-S", - maxsize = "-s", - numrotate = "-b", - localandnetworklog = "-L", - remotelogging = "-R", - }) - cmdparameter = variabletranslator[parameter] - - -- Report a error if someone tryes to use a invalid parameter - if not (cmdparameter) then - local availablevariables = "" - for k,v in pairs(variabletranslator) do - availablevariables = k .. ", " .. availablevariables - end - parameter = parameter or "" - return false, cfe({ - name="syslog.model.setconfigs()", - errtxt="'" .. parameter .. "' is not a valid parameter!\nValid options are: " .. availablevariables, - }) - end - - --TODO: Validate so that user cant add values with '-' (could cause major breakage next time you do getopts) - - -- This config-file only accepts one type of parameters (report error if someone uses wrong parameter) - if not (string.find(cmdparameter, "-%a$")) then - return false, cfe({ - name="syslog.model.setconfigs()", - errtxt="Parameter must be formated '-a' (where a is one upper/lowercase letter [a-z])", - }) - end - - -- Validate userinput (if valid path/filename) - if (value) and (cmdparameter == "-O") then - local cmdresult, cmdmessage = validator.is_valid_filename(value, "/var/log" ) - if not (cmdresult) then - return false, cfe({ - name="syslog.model.setconfigs()", - errtxt=cmdmessage, - }) - end - end - - -- Validate userinput (Has the user entered a valid hostname and/or port) - if (value) and (cmdparameter == "-R") then - local hostport = format.string_to_table(value, ":") - local host = hostport[1] - local port = hostport[2] - if (port) and not (validator.is_port(port)) then - return false, cfe({ - name="syslog.model.setconfigs.getopts.setoptsinfile()", - errtxt="You entered '" .. tostring(port) .. "' as port - This is not valid!", - }) - end - end - - -- Set/Unset checkbox variables - if (value) and ((cmdparameter == "-S") or (cmdparameter == "-L")) then value = "" end - - local cmdresult, cmdmessage, cmderror = getopts.setoptsinfile(configfile,variable,cmdparameter,value) - if (cmderror) then - return false, cfe({ - name="syslog.model.setconfigs.getopts.setoptsinfile()", - errtxt=cmderror, - }) - end - return true, cfe({ - name="syslog.model.setconfigs()", - value=cmdmessage, - }) -end - -- modifications should be a CFE function updatefilecontent (self, filetochange) local path = nil diff --git a/shorewall.menu b/shorewall.menu index 557f401..fac6de9 100644 --- a/shorewall.menu +++ b/shorewall.menu @@ -1,7 +1,7 @@ #CAT GROUP/DESC TAB ACTION Networking 40Firewall Status status +Networking 40Firewall Config config Networking 40Firewall Expert expert Networking 40Firewall Check check Networking 40Firewall Logfile logfile -Networking 40Firewall Config_(Example) config |