From f43bf637de7b6e2d698888ef4d878c13d9d99aa7 Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Fri, 22 Aug 2014 20:48:12 +0000 Subject: Initial commit for freeradius3 ACF Included support for status/startstop/logfile and list/edit/create/delete files --- Makefile | 44 +++++++++++++++ README | 1 + config.mk | 10 ++++ freeradius3-controller.lua | 29 ++++++++++ freeradius3-editfile-html.lsp | 1 + freeradius3-listfiles-html.lsp | 80 ++++++++++++++++++++++++++++ freeradius3-logfile-html.lsp | 6 +++ freeradius3-model.lua | 118 +++++++++++++++++++++++++++++++++++++++++ freeradius3-status-html.lsp | 1 + freeradius3.menu | 5 ++ freeradius3.roles | 3 ++ 11 files changed, 298 insertions(+) create mode 100644 Makefile create mode 100644 README create mode 100644 config.mk create mode 100644 freeradius3-controller.lua create mode 120000 freeradius3-editfile-html.lsp create mode 100644 freeradius3-listfiles-html.lsp create mode 100644 freeradius3-logfile-html.lsp create mode 100644 freeradius3-model.lua create mode 120000 freeradius3-status-html.lsp create mode 100644 freeradius3.menu create mode 100644 freeradius3.roles diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ad3f5f2 --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +APP_NAME=freeradius3 +PACKAGE=acf-$(APP_NAME) +VERSION=0.0.1 + +APP_DIST=\ + freeradius3* \ + + +EXTRA_DIST=README Makefile config.mk + +DISTFILES=$(APP_DIST) $(EXTRA_DIST) + +TAR=tar + +P=$(PACKAGE)-$(VERSION) +tarball=$(P).tar.bz2 +install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME) + +all: +clean: + rm -rf $(tarball) $(P) + +dist: $(tarball) + +install: + mkdir -p "$(install_dir)" + cp -a $(APP_DIST) "$(install_dir)" + +$(tarball): $(DISTFILES) + rm -rf $(P) + mkdir -p $(P) + cp -a $(DISTFILES) $(P) + $(TAR) -jcf $@ $(P) + rm -rf $(P) + +# target that creates a tar package, unpacks is and install from package +dist-install: $(tarball) + $(TAR) -jxf $(tarball) + $(MAKE) -C $(P) install DESTDIR=$(DESTDIR) + rm -rf $(P) + +include config.mk + +.PHONY: all clean dist install dist-install diff --git a/README b/README new file mode 100644 index 0000000..d66d025 --- /dev/null +++ b/README @@ -0,0 +1 @@ +ACF package for freeradius3 diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..45f4d21 --- /dev/null +++ b/config.mk @@ -0,0 +1,10 @@ +prefix=/usr +datadir=${prefix}/share +sysconfdir=${prefix}/etc +localstatedir=${prefix}/var +acfdir=${datadir}/acf +wwwdir=${acfdir}/www +cgibindir=${acfdir}/cgi-bin +appdir=${acfdir}/app +acflibdir=${acfdir}/lib +sessionsdir=${localstatedir}/lib/acf/sessions diff --git a/freeradius3-controller.lua b/freeradius3-controller.lua new file mode 100644 index 0000000..fbd149e --- /dev/null +++ b/freeradius3-controller.lua @@ -0,0 +1,29 @@ +local mymodule = {} + +mymodule.default_action = "status" + +function mymodule.status(self) + return self.model.get_status() +end + +function mymodule.startstop(self) + return self.handle_form(self, self.model.get_startstop, self.model.startstop_service, self.clientdata) +end + +function mymodule.listfiles(self) + return self.model.list_files() +end + +function mymodule.editfile(self) + return self.handle_form(self, self.model.get_file, self.model.update_file, self.clientdata, "Save", "Edit File", "File Saved") +end + +function mymodule.createfile(self) + return self.handle_form(self, self.model.getnewfile, self.model.createfile, self.clientdata, "Create", "Create New Freeradius File", "Freeradius File Created") +end + +function mymodule.deletefile(self) + return self.handle_form(self, self.model.getdeletefile, self.model.deletefile, self.clientdata, "Delete", "Delete Freeradius File", "Freeradius File Deleted") +end + +return mymodule diff --git a/freeradius3-editfile-html.lsp b/freeradius3-editfile-html.lsp new file mode 120000 index 0000000..15b1930 --- /dev/null +++ b/freeradius3-editfile-html.lsp @@ -0,0 +1 @@ +../filedetails-html.lsp \ No newline at end of file diff --git a/freeradius3-listfiles-html.lsp b/freeradius3-listfiles-html.lsp new file mode 100644 index 0000000..8fb4f33 --- /dev/null +++ b/freeradius3-listfiles-html.lsp @@ -0,0 +1,80 @@ +<% local view, viewlibrary, page_info, session = ... +htmlviewfunctions = require("htmlviewfunctions") +html = require("acf.html") +%> + +<% +function convertsize(size) + if string.find(size, "k$") then + return tonumber(string.match(size, "[%d.]*")) * 1024.0 + elseif string.find(size, "M$") then + return tonumber(string.match(size, "[%d.]*")) * 1024.0 * 1024.0 + elseif string.find(size, "G$") then + return tonumber(string.match(size, "[%d.]*")) + 1024.0 * 1024.0 * 1024.0 + else + return tonumber(string.match(size, "[%d.]*")) + end +end +%> + + + + + + + +<% htmlviewfunctions.displaycommandresults({"editfile", "deletefile"}, session) %> +<% htmlviewfunctions.displaycommandresults({"createfile"}, session, true) %> + +<% if viewlibrary and viewlibrary.dispatch_component then + viewlibrary.dispatch_component("status") +end %> + +<% local header_level = htmlviewfunctions.displaysectionstart(cfe({label="Configuration"}), page_info) %> + + + + + + + + +<% local filename = cfe({ type="hidden", value="" }) %> +<% local redir = cfe({ type="hidden", value=page_info.orig_action }) %> +<% for k,v in ipairs( view.value ) do %> + + + + + + +<% end %> +
ActionFileSizeLast Modified
+ <% filename.value = v.filename %> + <% if viewlibrary.check_permission("editfile") then %> + <% htmlviewfunctions.displayitem(cfe({type="link", value={filename=filename, redir=redir}, label="", option="Edit", action="editfile"}), page_info, -1) %> + <% end %> + <% if viewlibrary.check_permission("deletefile") then %> + <% htmlviewfunctions.displayitem(cfe({type="form", value={filename=filename}, label="", option="Delete", action="deletefile", class="deletefile"}), page_info, -1) %> + <% end %> + <%= html.html_escape(v.filename) %><%= convertsize(v.size) %>b<%= html.html_escape(v.size) %><%= html.html_escape(v.mtime) %>
+ +<% if viewlibrary and viewlibrary.dispatch_component and viewlibrary.check_permission("createfile") then + local createform = viewlibrary.dispatch_component("createfile", nil, true) + createform.action = page_info.script .. page_info.prefix .. page_info.controller .. "/createfile" + htmlviewfunctions.displayitem(createform, page_info, htmlviewfunctions.incrementheader(header_level)) +end %> +<% htmlviewfunctions.displaysectionend(header_level) %> diff --git a/freeradius3-logfile-html.lsp b/freeradius3-logfile-html.lsp new file mode 100644 index 0000000..edb192d --- /dev/null +++ b/freeradius3-logfile-html.lsp @@ -0,0 +1,6 @@ +<% local data, viewlibrary = ... +%> + +<% if viewlibrary and viewlibrary.dispatch_component then + viewlibrary.dispatch_component("alpine-baselayout/logfiles/view", {filename="/var/log/radius/radius.log"}) +end %> diff --git a/freeradius3-model.lua b/freeradius3-model.lua new file mode 100644 index 0000000..473219e --- /dev/null +++ b/freeradius3-model.lua @@ -0,0 +1,118 @@ +local mymodule = {} + +-- Load libraries +modelfunctions = require("modelfunctions") +posix = require("posix") +fs = require("acf.fs") +format = require("acf.format") +validator = require("acf.validator") + +-- Set variables +local processname = "radiusd" +local packagename = "freeradius3" +local baseurl = "/etc/raddb" +local owner = "radius" +local group = "root" + +-- ################################################################################ +-- LOCAL FUNCTIONS + +local is_valid_filename = function(filename) + local dirname = posix.dirname(filename) + return validator.is_valid_filename(filename) and string.match(dirname, baseurl) and not string.match(dirname, "%.%.") +end + +-- ################################################################################ +-- PUBLIC FUNCTIONS + +function mymodule.get_status() + return modelfunctions.getstatus(processname, packagename, "Freeradius Status") +end + +function mymodule.get_startstop(self, clientdata) + return modelfunctions.get_startstop(processname) +end + +function mymodule.startstop_service(self, startstop, action) + return modelfunctions.startstop_service(startstop, action) +end + +function mymodule.get_file(self, clientdata) + local filename = clientdata.filename + return modelfunctions.getfiledetails(filename, is_valid_filename) +end + +function mymodule.update_file(self, filedetails) + local ret = modelfunctions.setfiledetails(self, filedetails, is_valid_filename) + if not ret.errtxt then + posix.chmod(filedetails.value.filename.value, "rw-r-----") + posix.chown(filedetails.value.filename.value, posix.getpasswd(owner, "uid") or 0, posix.getpasswd(group, "gid") or 0) + end + return ret +end + +function mymodule.list_files() + local retval = {} + for file in fs.find(null, baseurl) do + local details = fs.stat(file) + if details.type == "regular" then + details.filename = file + table.insert(retval, details) + end + end + table.sort(retval, function(a,b) return a.filename < b.filename end) + return cfe({ type="structure", value=retval, label="List of Freeradius files" }) +end + +function mymodule.getnewfile() + local filename = cfe({ label="File Name", descr="Must be in "..baseurl }) + return cfe({ type="group", value={filename=filename}, label="Freeradius File" }) +end + +function mymodule.createfile(self, filedetails) + local success = true + local path = string.match(filedetails.value.filename.value, "^%s*(.*%S)%s*$") or "" + if not string.find(path, "/") then + path = baseurl.."/"..path + end + + if not is_valid_filename(path) then + success = false + filedetails.value.filename.errtxt = "Invalid filename" + else + if not fs.is_dir(baseurl) then fs.create_directory(baseurl) end + if posix.stat(path) then + success = false + filedetails.value.filename.errtxt = "Filename already exists" + end + end + + if success then + fs.create_file(path) + else + filedetails.errtxt = "Failed to Create File" + end + + return filedetails +end + +function mymodule.getdeletefile(self, clientdata) + local retval = {} + retval.filename = cfe({ label="File Name", value=clientdata.filename or "" }) + return cfe({ type="group", value=retval, label="Delete Freeradius File" }) +end + +function mymodule.deletefile(self, delfile) + delfile.errtxt = "Failed to delete Freeradius File - invalid filename" + for i,file in ipairs(mymodule.list_files().value) do + if delfile.value.filename.value == file.filename then + delfile.errtxt = nil + os.remove(delfile.value.filename.value) + break + end + end + + return delfile +end + +return mymodule diff --git a/freeradius3-status-html.lsp b/freeradius3-status-html.lsp new file mode 120000 index 0000000..b2f8480 --- /dev/null +++ b/freeradius3-status-html.lsp @@ -0,0 +1 @@ +../status-html.lsp \ No newline at end of file diff --git a/freeradius3.menu b/freeradius3.menu new file mode 100644 index 0000000..24925a1 --- /dev/null +++ b/freeradius3.menu @@ -0,0 +1,5 @@ +# Prefix and controller are already known at this point +# Cat Group Tab Action +Applications 87Freeradius Status status +Applications 87Freeradius Expert listfiles +Applications 87Freeradius Logfile logfile diff --git a/freeradius3.roles b/freeradius3.roles new file mode 100644 index 0000000..49d3fa7 --- /dev/null +++ b/freeradius3.roles @@ -0,0 +1,3 @@ +USER=freeradius3:status,freeradius3:startstop,freeradius3:logfile +EXPERT=freeradius3:listfiles,freeradius3:editfile,freeradius3:createfile,freeradius3:deletefile +ADMIN=freeradius3:status,freeradius3:startstop,freeradius3:logfile,freeradius3:listfiles,freeradius3:editfile,freeradius3:createfile,freeradius3:deletefile -- cgit v1.2.3