summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openssh-config-html.lsp34
-rw-r--r--openssh-connectedpeers-html.lsp31
-rw-r--r--openssh-controller.lua74
l---------[-rw-r--r--]openssh-expert-html.lsp17
-rw-r--r--openssh-model.lua201
l---------[-rw-r--r--]openssh-startstop-html.lsp24
l---------[-rw-r--r--]openssh-status-html.lsp19
7 files changed, 112 insertions, 288 deletions
diff --git a/openssh-config-html.lsp b/openssh-config-html.lsp
index e76d1a2..6990014 100644
--- a/openssh-config-html.lsp
+++ b/openssh-config-html.lsp
@@ -1,38 +1,18 @@
-<% local form, viewlibrary, page_info, session = ...
+<% local form, viewlibrary, page_info = ...
require("viewfunctions")
---[[
-io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
-io.write(html.cfe_unpack(form))
-io.write("</span>")
---]]
%>
<% if viewlibrary and viewlibrary.dispatch_component then
viewlibrary.dispatch_component("status")
end %>
-<H1>Configuration</H1>
-<H2>Guided Configuration</H2>
-<FORM NAME="configuration" ACTION="" METHOD="POST">
-<H3>Settings</H3>
-<DL>
-<%
-local myform = form
-local tags = { "Port", "ListenAddress", "PasswordAuthentication", "UseDNS",}
-displayinfo(myform,tags)
+<H1><%= form.label %></H1>
+<%
+ form.action = page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action
+ local order = {"Port", "ListenAddress", "PermitRootLogin", "PasswordAuthentication", "UseDNS"}
+ displayform(form, order)
%>
-</DL>
-<H3>Save</H3>
-<DL>
-<%
-local myform = form
-local tags = { "cmdsave",}
-displayinfo(myform,tags)
-%>
-</DL>
-</FORM>
-
-<% if viewlibrary and viewlibrary.dispatch_component and session.permissions[page_info.controller].startstop then
+<% if viewlibrary and viewlibrary.dispatch_component then
viewlibrary.dispatch_component("startstop")
end %>
diff --git a/openssh-connectedpeers-html.lsp b/openssh-connectedpeers-html.lsp
index 9fdbca8..5657e36 100644
--- a/openssh-connectedpeers-html.lsp
+++ b/openssh-connectedpeers-html.lsp
@@ -10,34 +10,41 @@ io.write("</span>")
<H1>Connected peers</H1>
<DL>
<%
+if #data == 0 then
+ io.write("No peers found\n")
+end
local col1="180px"
for k,v in pairs(data) do
- io.write("<H3>" .. (tostring(v.host) or "unkown") .. "</H3>")
+ io.write("<H3>" .. v.host)
+ if v.name and v.name ~= "" then io.write(" - "..v.name) end
+ io.write("</H3>\n")
io.write("<TABLE>")
for i=1, v.cnt do
io.write("<TR>")
if (v.tty[i]) then
io.write("<TD WIDTH='20px' STYLE='padding-left:20px;vertical-align:top;'><IMG SRC='/skins/static/tango/16x16/apps/utilities-terminal.png' HEIGHT='16' WIDTH='16'></TD>")
- io.write("<TD STYLE='padding-bottom:10px'>")
+ io.write("<TD STYLE='padding-bottom:10px'>\n")
io.write("<TABLE>")
- io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session TTY:</TD><TD>".. tostring(v.tty[i]['tty']) .. "</TD></TR>")
- io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session Started:</TD><TD>".. tostring(v.tty[i]['time']) .. "</TD></TR>")
- io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session Idle:</TD><TD>".. tostring(v.tty[i]['idle']) .. "</TD></TR>")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session user:</TD><TD>".. v.tty[i].user .. "</TD></TR>\n")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session TTY:</TD><TD>".. v.tty[i].tty .. "</TD></TR>\n")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session Started:</TD><TD>".. v.tty[i].time .. "</TD></TR>\n")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session Idle:</TD><TD>".. v.tty[i].idle .. "</TD></TR>\n")
io.write("</TABLE>")
- io.write("</TD>")
+ io.write("</TD>\n")
else
io.write("<TD WIDTH='20px' STYLE='padding-left:20px;vertical-align:top;'><IMG SRC='/skins/static/tango/16x16/emblems/emblem-unreadable.png' HEIGHT='16' WIDTH='16'></TD>")
- io.write("<TD STYLE='padding-bottom:10px'>")
+ io.write("<TD STYLE='padding-bottom:10px'>\n")
io.write("<TABLE>")
- io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session TTY:</TD><TD>No records</TD></TR>")
- io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session Started:</TD><TD>No records</TD></TR>")
- io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session Idle:</TD><TD>No records</TD></TR>")
- io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Other:</TD><TD>This could be a sshfs session</TD></TR>")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session user:</TD><TD>No records</TD></TR>\n")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session TTY:</TD><TD>No records</TD></TR>\n")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session Started:</TD><TD>No records</TD></TR>\n")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Session Idle:</TD><TD>No records</TD></TR>\n")
+ io.write("<TR><TD WIDTH='"..col1.."' STYLE='font-weight:bold;'>Other:</TD><TD>This could be a sshfs session</TD></TR>\n")
io.write("</TABLE>")
- io.write("</TD>")
+ io.write("</TD>\n")
end
io.write("</TR>")
end
diff --git a/openssh-controller.lua b/openssh-controller.lua
index 30800f5..6a76512 100644
--- a/openssh-controller.lua
+++ b/openssh-controller.lua
@@ -3,8 +3,6 @@ module(..., package.seeall)
-- Load libraries
require("controllerfunctions")
-local checkboxes = { "PermitRootLogin", "PasswordAuthentication", "UseDNS" }
-
default_action = "status"
function status(self)
@@ -12,75 +10,7 @@ function status(self)
end
function config(self)
- local output = {}
- local errtxt = {}
- local successfuledit
- if (self.clientdata.cmdsave) then
- local fields = { "Port", "ListenAddress", "PermitRootLogin", "PasswordAuthentication", "UseDNS", }
- local newconfig = {}
- for _ , v in pairs(fields) do
- newconfig[v] = self.clientdata[v] or ""
- end
- successfuledit, errtxt = self.model.write_config(newconfig)
- end
-
- local config = self.model.read_config() or {}
- output.cmdsave = cfe({
- name="cmdsave",
- label="Save above changes",
- value="Apply",
- type="submit",
- })
-
- output.Port = cfe({
- name="Port",
- label="Port",
- value=config.Port,
- })
- output.ListenAddress = cfe({
- name="ListenAddress",
- label="Listen address",
- value=config.ListenAddress,
- })
- output.PermitRootLogin = cfe({
- name="PermitRootLogin",
- label="Permit Root Login",
- })
-
- output.PasswordAuthentication = cfe({
- name="PasswordAuthentication",
- label="Password Authentication",
- })
-
- output.UseDNS = cfe({
- name="UseDNS",
- label="Use DNS",
- })
-
- -- Display checkboxes checked/unchecked
- for k,v in pairs(checkboxes) do
- output[v]['value']="yes"
- output[v]['type']="checkbox"
- if (config[v]) and (string.lower(tostring(config[v] or "")) == "yes") then
- output[v]['checked']="yes"
- end
- end
-
- -- Display results of previous save action
- if (self.clientdata.cmdsave) and not (successfuledit) then
- for k,v in pairs(self.clientdata) do
- if (output) and (output[k]) and (k) then
- output[k]['value'] = self.clientdata[k]
- output[k]['errtxt'] = errtxt[k]
- end
- end
-
- output.cmdsave.errtxt = "Save action was canceled because there was invalid input."
- elseif (self.clientdata.cmdsave) and (successfuledit) then
- output.cmdsave.descr = "* Configuration was succesfully saved"
- end
-
- return output
+ return controllerfunctions.handle_form(self, self.model.read_config, self.model.update_config, self.clientdata, "Save", "Edit Config", "Configuration Saved")
end
function startstop(self)
@@ -94,5 +24,3 @@ end
function connectedpeers(self)
return self.model.list_conn_peers()
end
-function welcome(self)
-end
diff --git a/openssh-expert-html.lsp b/openssh-expert-html.lsp
index d349048..207f324 100644..120000
--- a/openssh-expert-html.lsp
+++ b/openssh-expert-html.lsp
@@ -1,16 +1 @@
-<% local form, viewlibrary, page_info, session = ... %>
-<% require("viewfunctions") %>
-
-<% if viewlibrary and viewlibrary.dispatch_component then
- viewlibrary.dispatch_component("status")
-end %>
-
-<%
-local pattern = string.gsub(page_info.prefix..page_info.controller, "[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%1")
-local func = haserl.loadfile(page_info.viewfile:gsub(pattern..".*$", "/") .. "filedetails-html.lsp")
-func(form, viewlibrary, page_info, session)
-%>
-
-<% if viewlibrary and viewlibrary.dispatch_component and session.permissions[page_info.controller].startstop then
- viewlibrary.dispatch_component("startstop")
-end %>
+../expert-html.lsp \ No newline at end of file
diff --git a/openssh-model.lua b/openssh-model.lua
index 4df9abd..4aac198 100644
--- a/openssh-model.lua
+++ b/openssh-model.lua
@@ -4,8 +4,6 @@ module(..., package.seeall)
require("modelfunctions")
require("validator")
require("fs")
-require("posix")
-require("getopts")
-- Set variables
local configfile = "/etc/ssh/sshd_config"
@@ -14,92 +12,40 @@ local packagename = "openssh-server"
local header = "SSH"
local path="PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "
-local default = {
- Port = 22,
- ListenAddress = "0.0.0.0",
--- PermitRootLogin = true,
- PasswordAuthentication = true,
- UseDNS = true,
-}
-
-- ################################################################################
-- LOCAL FUNCTIONS
-local function parseconfigfile(file)
- file = file or ""
- local retval = {}
- for line in string.gmatch(file, "([^\n]+)\n?") do
- line = string.gsub(line, "#.*$", "")
- if line and line ~= "" then
- table.insert(retval, {})
- for word in string.gmatch(line, "%S+") do
- table.insert(retval[#retval], word)
- end
- end
- end
-
- return retval
-end
-
-- return "Yes" or "No" on true/false or value as string
local function config_value(value)
if type(value) == "boolean" then
if value then
- return "Yes"
+ return "yes"
else
- return "No"
+ return "no"
end
end
return tostring(value)
end
-local function validateconfig(config)
+local function validate_config(config)
+ local success = true
- if config.ListenAddress and not validator.is_ipv4(config.ListenAddress) then
- return false, { ['ListenAddress'] = "You entered invalid IP", }
+ if not validator.is_ipv4(config.value.ListenAddress.value) then
+ config.value.ListenAddress.errtxt = "Invalid IP"
+ success = false
end
-
- if config.Port and not validator.is_port(config.Port) then
- return false, { ['Port'] = "You entered invalid Port", }
+ if not validator.is_port(config.value.Port.value) then
+ config.value.Port.value = "Invalid Port"
+ success = false
end
- return true
+ return success, config
end
+
-- ################################################################################
-- PUBLIC FUNCTIONS
--- valid keywords and default config
-
-function read_config()
- local conf = {}
- local f = io.open(configfile, "r")
- local line, key, _, k, v
-
- if not f then
- return nil
- end
-
- -- clone default conf
- for k, v in pairs(default) do
- conf[k] = v
- end
-
- for line in f:lines() do
- line = string.gsub(line, "#.*", "")
- for key, _ in pairs(default) do
- local k,v = string.match(line, "^("..key..")%s+(.*)")
- if k then
- conf[k] = v
- end
- end
- end
- f:close()
- return conf
-end
-
-
-function startstop_service(action)require("getopts")
-
+function startstop_service(action)
return modelfunctions.startstop_service(processname, action)
end
@@ -116,49 +62,61 @@ function setconfigfile(filedetails)
return modelfunctions.setfiledetails(filedetails)
end
-function write_config(config)
- local k, v, lines, i,j
- local errtxt = {}
- local conf = {}
+function read_config()
+ local output = {}
+ output.Port = cfe({ value=22, label="Port" })
+ output.ListenAddress = cfe({ value="0.0.0.0", label="Listen address" })
+ output.PermitRootLogin = cfe({ type="boolean", value=true, label="Permit Root Login" })
+ output.PasswordAuthentication = cfe({ type="boolean", value=true, label="Password Authentication" })
+ output.UseDNS = cfe({ type="boolean", value=true, label="Use DNS" })
+
+ local config = format.parse_configfile(fs.read_file(configfile))
+ if config then
+ output.Port.value = config.Port or output.Port.value
+ output.ListenAddress.value = config.ListenAddress or output.ListenAddress.value
+ output.PermitRootLogin.value = not (config.PermitRootLogin == "no")
+ output.PasswordAuthentication.value = not (config.PasswordAuthentication == "no")
+ output.UseDNS.value = not (config.UseDNS == "no")
+ end
+
+ return cfe({ type="group", value=output, label="OpenSSH Config" })
+end
- local validated, errtxt = validateconfig(config)
- if not validated then
- return false, errtxt
- end
+function update_config(config)
+ local success, config = validate_config(config)
- -- filter out unsupported keys
- for k,v in pairs(default) do
- if (config[k] == nil) or (config[k] == "") then
- conf[k] = "no"
- else
- conf[k] = config[k]
+ if success then
+ for name,val in pairs(config.value) do
+ val.line = name.." "..config_value(val.value)
end
- end
- lines = fs.read_file_as_array(configfile) or {}
- for i, j in ipairs(lines) do
- for k, v in pairs(conf) do
- if string.match(j, "^#?"..k.."%s+") then
- lines[i] = k .. " " .. config_value(v)
- conf[k] = nil
+ local lines = {}
+ for line in string.gmatch(fs.read_file(configfile) or "", "([^\n]*)\n?") do
+ for name,val in pairs(config.value) do
+ if val.line and string.find(line, "^%s*#?%s*"..name) then
+ if string.find(line, "^%s*#") then
+ lines[#lines+1] = val.line
+ else
+ line = val.line
+ end
+ val.line = nil
+ end
end
+ lines[#lines+1] = line
end
- end
- -- append config opts to end
- for k,v in pairs(conf) do
- table.insert(lines, k .. " " .. config_value(v))
+ for name,val in pairs(config.value) do
+ if val.line then
+ lines[#lines+1] = val.line
+ val.line = nil
+ end
+ end
+ fs.write_file(configfile, string.gsub(table.concat(lines, "\n"), "\n+$", ""))
+ else
+ config.errtxt = "Failed to save config"
end
- -- write file
- posix.mkdir(posix.dirname(configfile))
- local f = io.open(configfile, "w")
- for _,i in ipairs(lines) do
- f:write(i.."\n")
- end
- f:close()
-
- return true
+ return config
end
function list_conn_peers()
@@ -167,42 +125,47 @@ function list_conn_peers()
local ps = {}
local who = {}
config = read_config()
- local f = io.popen( path .. 'netstat -lna | grep ' .. tostring(config.Port) .. ' | grep "ESTABLISHED"' )
+ local f = io.popen( path .. 'netstat -lna | grep ":' .. tostring(config.value.Port.value) .. ' " | grep "ESTABLISHED"' )
for line in f:lines() do
- local peer = string.match(line, "^%S*%s*%S*%s*%S*%s*%S*%s*(%S*)")
- peer = string.match(peer, "(%d*%.%d*%.%d*%.%d*):%d*$")
- if (peer) then
- if not (netstat[peer]) then netstat[peer] = {cnt=0} end
- netstat[peer]['cnt'] = (tonumber(netstat[peer]['cnt']) + 1)
+ local peer = string.match(line, "^%S+%s+%S+%s+%S+%s+%S+%s+(%S+)")
+ peer = string.match(peer, "(%d+%.%d+%.%d+%.%d+):%d*$")
+ if peer then
+ if not netstat[peer] then
+ local g = io.popen( path .. "dnsname " .. peer)
+ local name = g:read("*l")
+ g:close()
+ netstat[peer] = {cnt=0, name=name}
+ end
+ netstat[peer].cnt = netstat[peer].cnt + 1
end
end
f:close()
local f = io.popen( path .. 'ps | grep "sshd:" | grep -v "grep"' )
for line in f:lines() do
- table.insert(ps, string.match(line,".-%@(%S*)$"))
+ table.insert(ps, string.match(line,"@(%S+)"))
end
f:close()
for peer,v in pairs(netstat) do
- if not (netstat[peer]['tty']) then netstat[peer]['tty'] = {} end
- local f = io.popen( path .. 'who | grep "' .. tostring(peer) .. '" | egrep "' .. table.concat(ps, "|") .. '"' )
+ if not (netstat[peer].tty) then netstat[peer].tty = {} end
+ local cmd = path .. 'who | egrep "' .. peer
+ if v.name and v.name ~= "" then cmd = cmd .. '|' .. v.name end
+ cmd = cmd .. '" | egrep "' .. table.concat(ps, "|") .. '"'
+ local f = io.popen( cmd )
for line in f:lines() do
local user,tty,idle,time = string.match(line, "^(%S*)%s*(%S*)%s*(%S*)%s*(%S*%s*%S*%s*%S*)")
- table.insert(netstat[peer]['tty'], {
- user=user,
- tty=tty,
- idle=idle,
- time=time,
+ table.insert(netstat[peer].tty, {
+ user=user,
+ tty=tty,
+ idle=idle,
+ time=time,
})
end
f:close()
- end
-
- for k,v in pairs(netstat) do
table.insert(output, v)
- output[#output]['host'] = k
+ output[#output]['host'] = peer
end
return output
diff --git a/openssh-startstop-html.lsp b/openssh-startstop-html.lsp
index 56404f9..0ea2627 100644..120000
--- a/openssh-startstop-html.lsp
+++ b/openssh-startstop-html.lsp
@@ -1,23 +1 @@
-<% local data, viewlibrary, page_info = ... %>
-
-<H1>Management</H1>
-<DL>
-<form action="<%= page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action %>" method="POST">
-<DT>Program control-panel</DT>
-<DD>
-<input class="submit" type="submit" name="action" value="Start" <% if data.value.status.value== "Enabled" then io.write("disabled") end %>>
-<input class="submit" type="submit" name="action" value="Stop" <% if data.value.status.value== "Disabled" then io.write("disabled") end %>>
-<input class="submit" type="submit" name="action" value="Restart" <% if data.value.status.value== "Disabled" then io.write("disabled") end %>>
-</DD>
-</form>
-
-<% if data.value.result then %>
-<DT>Previous action result</DT>
-<DD>
-<% if data.value.result.descr then %>
-<P CLASS='descr'><%= string.gsub(data.value.result.descr, "\n", "<BR>") %></P>
-<% end if data.value.result.errtxt then %>
-<P CLASS='error'><%= string.gsub(data.value.result.errtxt, "\n", "<BR>") %></P>
-<% end end %>
-</DD>
-</DL>
+../startstop-html.lsp \ No newline at end of file
diff --git a/openssh-status-html.lsp b/openssh-status-html.lsp
index c126d2e..b2f8480 100644..120000
--- a/openssh-status-html.lsp
+++ b/openssh-status-html.lsp
@@ -1,18 +1 @@
-<% local data, viewlibrary, page_info, session = ...
-require("viewfunctions")
---[[
-io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
-io.write(html.cfe_unpack(data))
-io.write("</span>")
---]]
-%>
-
-<H1>System Info</H1>
-<DL>
-<%
-displayitem(data.value.status)
-displayitem(data.value.version)
-displayitem(data.value.autostart)
-%>
-</DL>
-
+../status-html.lsp \ No newline at end of file