From 1d4de0dba3e3cc249b59143e2872e0a5f7c9ccde Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Wed, 1 Apr 2009 14:44:51 +0000 Subject: Fixed openssh authorized keys parsing to allow for access phrase and arbitrary characters. --- openssh-listauth-html.lsp | 6 +++++- openssh-model.lua | 45 +++++++++++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/openssh-listauth-html.lsp b/openssh-listauth-html.lsp index d93bc8b..dc2507c 100644 --- a/openssh-listauth-html.lsp +++ b/openssh-listauth-html.lsp @@ -14,7 +14,11 @@ <% for i,auth in ipairs(view.value.auth.value) do %> - <%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/deleteauth?user="..view.value.user.value.."&auth="..auth.id, label="Delete "} %> +
" method="POST"> + + + +
<%= html.html_escape(auth.id) %> <% if #auth.key>32 then io.write(html.html_escape(string.sub(auth.key,0,16)) .. " ... " .. html.html_escape(string.sub(auth.key, -16))) else io.write(html.html_escape(auth.key)) end %> diff --git a/openssh-model.lua b/openssh-model.lua index 12f3f6a..3b8718b 100644 --- a/openssh-model.lua +++ b/openssh-model.lua @@ -2,6 +2,7 @@ module(..., package.seeall) -- Load libraries require("modelfunctions") +require("posix") require("validator") require("fs") require("format") @@ -182,13 +183,30 @@ 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 + -- The only users we're going to worry about in this ACF are root and ones with home directories + for user in posix.files("/home") do + if fs.is_dir("/home/" .. user) and not string.find(user, "^%.") then users[#users + 1] = user end end return cfe({ type="list", value=users, label="User list" }) end +local function parseauthline(line) + local retval = {} + local words = format.string_to_table(line, "%s") + if string.match(words[1], "^ssh%-%ws%w$") then + retval.perm = "" + retval.key = words[2] + retval.id = table.concat(words, " ", 3) + elseif string.match(words[2], "^ssh%-%ws%w$") then + retval.perm = words[1] + retval.key = words[3] + retval.id = table.concat(words, " ", 4) + else + retval = nil + end + return retval +end + function list_auths(user) user = user or "root" local cmdresult = cfe({ type="group", value={}, label="Authorized Key List" }) @@ -201,8 +219,7 @@ function list_auths(user) 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}) + table.insert(cmdresult.value.auth.value, parseauthline(line)) end end return cmdresult @@ -220,7 +237,8 @@ function delete_auth(user, auth) if data then local newdata = {} for line in string.gmatch(data, "([^\n]+)\n?") do - if string.match(line, "%s(%S+)$") == auth then + local val = parseauthline(line) + if val.id == auth then cmdresult.value = "Deleted key" cmdresult.errtxt = nil else @@ -251,11 +269,9 @@ function create_auth(authstr) 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.value = string.gsub(format.dostounix(authstr.value.cert.value), "\n", "") + local val = parseauthline(authstr.value.cert.value) + if not val then authstr.value.cert.errtxt = "Invalid format" success = false end @@ -267,9 +283,10 @@ function create_auth(authstr) 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" + for line in string.gmatch(data, "([^\n]+)\n?") do + local val2 = parseauthline(line) + if val.id == val2.id or val.key == val2.key then + authstr.value.cert.errtxt = "This key / ID already exists" success = false break end -- cgit v1.2.3