module(..., package.seeall) require("fs") require("procps") require("getopts") require("format") require("daemoncontrol") require("validator") local configfile = "/etc/shorewall/shorewall.conf" local processname = "shorewall" local baseurl = "/etc/shorewall/" local config = {} local function getloglevels() local loglevels = {} for i=1,8 do table.insert(loglevels,i) end return loglevels end local function getdetails() local f,error = io.popen("/sbin/shorewall status") local fake = f:read("*l") local fake = f:read("*l") local programstatus = f:read("*l") or "" local programstate = f:read("*l") or "" f:close() local f,error = io.popen("/sbin/shorewall version") local programversion = "shorewall-" .. f:read("*l") f:close() return programversion,programstatus,programstate end local function read_config(file) local path = baseurl .. file if not (fs.is_file(path)) then return {} end local filecontent = fs.read_file_as_array(path) local output = {} for k,v in pairs(filecontent) do if not string.find ( v, "^[;#].*" ) then table.insert(output, v) end end return output end -- ################################################################################ -- PUBLIC FUNCTIONS -- action should be a CFE function startstop_service ( self, action ) local cmd = action.value local cmdresult,cmdmessage,cmderror,cmdaction = daemoncontrol.daemoncontrol(processname, cmd) action.descr=cmdmessage action.errtxt=cmderror -- Reporting back (true|false, the original acition) return cmdresult,action end function getconfig() local config = {} config.params_list = cfe({ name = "params_list", label="List of parameters", type="select", option=read_config("params"), }) config.params_list.size=#config.params_list.option + 1 config.interfaces_list = cfe({ name = "interfaces_list", label="List of interfaces", type="select", option=read_config("interfaces"), }) config.interfaces_list.size=#config.interfaces_list.option + 1 config.zones_list = cfe({ name = "zones_list", label="List of zones", type="select", option=read_config("zones"), }) config.zones_list.size=#config.zones_list.option + 1 config.policies_list = cfe({ name = "policies_list", label="List of policies", type="select", option=read_config("policy"), }) config.policies_list.size=#config.policies_list.option + 1 config.rules_list = cfe({ name = "rules_list", label="List of rules", type="select", option=read_config("rules"), }) config.rules_list.size=#config.rules_list.option + 1 return config end function getstatus() local status = {} local programversion,programstatus,programstate = getdetails() status.version = cfe({ name = "version", label="Program version", value=programversion, }) status.status = cfe({ name="status", label="Program status", value=programstatus, }) status.state = cfe({ name="state", label="Program reports", value=programstate, }) return status end function configcheck () local check = {} local f,err = io.popen("/bin/echo -n '>> Check starts at: ';/bin/date; /bin/echo; /etc/init.d/shorewall check; /bin/echo; /bin/echo -n '>> Check stops at: '; /bin/date;") local checkresult = f:read("*a") f:close() check.checkresult = cfe({ name = "checkresult", type="longtext", label="Result of checking config", value=checkresult, }) return check end function getlogfile () local logfile = {} local cmdaction = "cat /var/log/messages | grep Shorewall" local f, error = io.popen(cmdaction ,r) local checkresult = f:read("*a") f:close() logfile.checkresult = cfe({ name = "checkresult", type="longtext", label="Result of logfiles", value=checkresult, }) logfile.filename = cfe({ name="filename", label="File name", value=cmdaction, }) return logfile end function getfilelist () local filepath = baseurl local listed_files = {} local k,v for name in posix.files(filepath) do if not string.match(name, "^%.") and not string.match(name, "^Makefile") then local filedetails = fs.stat(filepath .. name) table.insert ( listed_files , cfe({name=name, value=filepath .. name, mtime=filedetails.mtime, size=filedetails.size,}) ) end end table.sort(listed_files, function (a,b) return (a.name < b.name) end ) return listed_files end function getfiledetails(self,search) local file = {} local path = nil --Validate filename local available_files = getfilelist() for k,v in pairs(available_files) do if ( tostring(available_files[k]["value"]) == tostring(search.value) ) then path = tostring(search.value) end end if not (path) or (path == "") then file["filename"] = search file["filename"]["label"] = "File name" file["filename"]["errtxt"] = "Invalid path!" return file end local filedetails = fs.stat(path) file["filename"] = cfe({ name="filename", label="File name", value=path, }) file["filesize"] = cfe({ name="filesize", label="File size", value=filedetails.size, }) file["mtime"] = cfe({ name="mtime", label="File name", value=filedetails.mtime, }) file["filecontent"] = cfe({ type="longtext", name="filecontent", label="File content", value=fs.read_file(path), }) 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 --Validate filename local available_files = getfilelist() for k,v in pairs(available_files) do if ( tostring(available_files[k]["value"]) == tostring(filetochange.name) ) then path = tostring(filetochange.name) end end if not (path) then filetochange.errtxt = "Invalid path!" return filetochange end local file_result,err = fs.write_file(path, format.dostounix(filetochange.value)) return file_result, err end