diff options
-rw-r--r-- | openssh-addauth-html.lsp | 10 | ||||
-rw-r--r-- | openssh-controller.lua | 16 | ||||
-rw-r--r-- | openssh-listauth-html.lsp | 25 | ||||
-rw-r--r-- | openssh-listusers-html.lsp | 10 | ||||
-rw-r--r-- | openssh-model.lua | 110 | ||||
-rw-r--r-- | openssh.menu | 1 | ||||
-rw-r--r-- | openssh.roles | 4 |
7 files changed, 174 insertions, 2 deletions
diff --git a/openssh-addauth-html.lsp b/openssh-addauth-html.lsp new file mode 100644 index 0000000..68ced32 --- /dev/null +++ b/openssh-addauth-html.lsp @@ -0,0 +1,10 @@ +<% local form, viewlibrary, page_info = ... +require("viewfunctions") +%> + +<H1><%= form.label %></H1> +<% + form.action = page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action + form.value.user.type = "hidden" + displayform(form) +%> diff --git a/openssh-controller.lua b/openssh-controller.lua index 6a76512..2ebf0da 100644 --- a/openssh-controller.lua +++ b/openssh-controller.lua @@ -24,3 +24,19 @@ end function connectedpeers(self) return self.model.list_conn_peers() end + +function listusers(self) + return self.model.list_users() +end + +function listauth(self) + return self.model.list_auths(self.clientdata.user) +end + +function deleteauth(self) + return self:redirect_to_referrer(self.model.delete_auth(self.clientdata.user, self.clientdata.auth)) +end + +function addauth(self) + return controllerfunctions.handle_form(self, function() return self.model.get_auth(self.clientdata.user) end, self.model.create_auth, self.clientdata, "Add", "Add New Authorized Key", "Key Added") +end diff --git a/openssh-listauth-html.lsp b/openssh-listauth-html.lsp new file mode 100644 index 0000000..f54a08a --- /dev/null +++ b/openssh-listauth-html.lsp @@ -0,0 +1,25 @@ +<% local view, viewlibrary, page_info, session = ... %> +<% require("viewfunctions") %> + +<% displaycommandresults({"deleteauth"}, session) %> +<% displaycommandresults({"addauth"}, session, true) %> + +<H1>Authorized Keys for <%= view.value.user.value %></H1> +<DL><TABLE> + <TR style="background:#eee;font-weight:bold;"> + <TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Action</TD> + <TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">ID</TD> + <TD style="white-space:nowrap;text-align:left;" class="header">Key</TD> + </TR> +<% for i,auth in ipairs(view.value.auth.value) do %> + <TR> + <TD style="padding-right:20px;white-space:nowrap;"> + <%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/deleteauth?user="..view.value.user.value.."&auth="..auth.id, label="Delete "} %> + </TD> + <TD style="padding-right:20px;white-space:nowrap;"><%= auth.id %></TD> + <TD style="white-space:nowrap;"><% if #auth.key>32 then io.write(string.sub(auth.key,0,16) .. " ... " .. string.sub(auth.key, -16)) else io.write(auth.key) end %></TD> + </TR> +<% end %> +</TABLE></DL> + +<% viewlibrary.dispatch_component("addauth", {user=view.value.user.value}) %> diff --git a/openssh-listusers-html.lsp b/openssh-listusers-html.lsp new file mode 100644 index 0000000..f49eb58 --- /dev/null +++ b/openssh-listusers-html.lsp @@ -0,0 +1,10 @@ +<% local view, viewlibrary, page_info, session = ... %> +<% require("viewfunctions") %> + +<H1>System User Accounts</H1> +<DL> +<% for i,user in ipairs(view.value) do %> + <DT><IMG SRC='/skins/static/tango/16x16/apps/system-users.png' HEIGHT='16' WIDTH='16'> <%= user %></DT> + <DD><A HREF='listauth?user=<%= user %>'>Edit this account</A></DD> +<% end %> +</DL> diff --git a/openssh-model.lua b/openssh-model.lua index 93997e4..8875f04 100644 --- a/openssh-model.lua +++ b/openssh-model.lua @@ -169,3 +169,113 @@ function list_conn_peers() return output end + +function list_users() + local users = {"root"} + for dir in fs.find(null, "/home/") do + local user = basename(dir) + if fs.is_dir(dir) and not string.find(user, "^%.") then users[#users + 1] = user end + end + return cfe({ type="list", value=users, label="User list" }) +end + +function list_auths(user) + user = user or "root" + local cmdresult = cfe({ type="group", value={}, label="Authorized Key List" }) + cmdresult.value.user = cfe({ value=user, label="User" }) + cmdresult.value.auth = cfe({ type="structure", value={}, label="Authorized Keys" }) + if not user == "root" and (string.find(user, "/") or not fs.is_dir("/home/"..user)) then + cmdresult.value.user.errtxt = "Invalid user" + else + local file = "/"..user.."/.ssh/authorized_keys" + if user ~= "root" then file = "/home"..file end + local data = fs.read_file(file) or "" + for line in string.gmatch(data, "([^\n]+)\n?") do + local typ,key,id = string.match(line, "(%S+)%s(%S+)%s(%S+)") + table.insert(cmdresult.value.auth.value, {key=key, id=id}) + end + end + return cmdresult +end + +function delete_auth(user, auth) + user = user or "root" + local cmdresult = cfe({ value="Failed to delete key", errtxt="User not found", label="Delete Authorized Key Result" }) + if user == "root" or (not string.find(user, "/") and fs.is_dir("/home/"..user)) then + cmdresult.errtxt = "Key not found" + + local file = "/"..user.."/.ssh/authorized_keys" + if user ~= "root" then file = "/home"..file end + local data = fs.read_file(file) + if data then + local newdata = {} + for line in string.gmatch(data, "([^\n]+)\n?") do + if string.match(line, "%s(%S+)$") == auth then + cmdresult.value = "Deleted key" + cmdresult.errtxt = nil + else + newdata[#newdata + 1] = line + end + end + if not cmdresult.errtxt then + fs.write_file(file, table.concat(newdata, "\n")) + end + end + end + return cmdresult +end + +function get_auth(user) + user = user or "root" + local cmdresult = cfe({ type="group", value={}, label="Authorized Key List" }) + cmdresult.value.user = cfe({ value=user, label="User" }) + cmdresult.value.cert = cfe({ type="longtext", label="SSH Certificate Contents" }) + return cmdresult +end + +function create_auth(authstr) + authstr.value.user.value = authstr.value.user.value or "root" + local success = true + if not authstr.value.user.value == "root" and (string.find(authstr.value.user.value, "/") or not fs.is_dir("/home/"..authstr.value.user.value)) then + authstr.value.user.errtxt = "Invalid user" + success = false + end + -- not sure how to validate the cert + authstr.value.cert.value = string.match(authstr.value.cert.value, "^[%s\n]*(.*%S)[%s\n]*$") or "" + if authstr.value.cert.value == "" then + authstr.value.cert.errtxt = "Cert cannot be empty" + success = false + elseif not string.match(authstr.value.cert.value, "ssh%-%S+%s%S+%s%S+$") then + authstr.value.cert.errtxt = "Invalid format" + success = false + end + if success then + local file = "/"..authstr.value.user.value.."/.ssh/authorized_keys" + if authstr.value.user.value ~= "root" then file = "/home"..file end + local data = fs.read_file(file) + if not data then + posix.mkdir(dirname(file)) + data = "" + end + if string.match(data, "^[%s\n]*$") then + data = authstr.value.cert.value + else + data = string.match(data, "^[%s\n]*(.*%S)[%s\n]*$") + for id in string.gmatch(data, "([^\n]+)\n?") do + if string.match(id, "%S+$") == string.match(authstr.value.cert.value, "%S+$") then + authstr.value.cert.errtxt = "This ID already exists" + success = false + break + end + end + data = string.gsub(data, "\n*$", "\n"..authstr.value.cert.value) + end + if success then + fs.write_file(file, data) + end + end + if not success then + authstr.errtxt = "Failed to add key" + end + return authstr +end diff --git a/openssh.menu b/openssh.menu index 173160d..5cd8758 100644 --- a/openssh.menu +++ b/openssh.menu @@ -1,5 +1,6 @@ #CAT GROUP/DESC TAB ACTION Networking 20SSH Status welcome Networking 20SSH Config config +Networking 20SSH Authorized_Users listusers Networking 20SSH Expert expert #Networking 20SSH Logfile logfile diff --git a/openssh.roles b/openssh.roles index 2a17764..a569149 100644 --- a/openssh.roles +++ b/openssh.roles @@ -1,4 +1,4 @@ USER=openssh:status,openssh:logfile,openssh:connectedpeers,openssh:welcome,openssh:startstop -EDITOR=openssh:config +EDITOR=openssh:config,openssh:listusers,openssh:listauth,openssh:deleteauth,openssh:addauth EXPERT=openssh:expert -ADMIN=openssh:status,openssh:logfile,openssh:connectedpeers,openssh:welcome,openssh:startstop,openssh:config,openssh:expert +ADMIN=openssh:status,openssh:logfile,openssh:connectedpeers,openssh:welcome,openssh:startstop,openssh:config,openssh:listusers,openssh:listauth,openssh:deleteauth,openssh:addauth,openssh:expert |