From 447f0c81713e567706c970d5c8fdea732dac52d4 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Tue, 20 Nov 2018 10:50:03 +0100 Subject: [PATCH] luci-mod-system: restructure administration pages Split password, dropbear and SSH key configuration into separate pages in order to improve the form layout and to simplify the code. Signed-off-by: Jo-Philipp Wich --- .../luasrc/controller/admin/system.lua | 76 +++++- .../luasrc/model/cbi/admin_system/admin.lua | 124 --------- .../model/cbi/admin_system/dropbear.lua | 53 ++++ .../luasrc/view/admin_system/password.htm | 70 +++++ .../luasrc/view/admin_system/sshkeys.htm | 245 ++++++++++++++++++ 5 files changed, 433 insertions(+), 135 deletions(-) delete mode 100644 modules/luci-mod-system/luasrc/model/cbi/admin_system/admin.lua create mode 100644 modules/luci-mod-system/luasrc/model/cbi/admin_system/dropbear.lua create mode 100644 modules/luci-mod-system/luasrc/view/admin_system/password.htm create mode 100644 modules/luci-mod-system/luasrc/view/admin_system/sshkeys.htm diff --git a/modules/luci-mod-system/luasrc/controller/admin/system.lua b/modules/luci-mod-system/luasrc/controller/admin/system.lua index 68ca88b98..3e58896d6 100644 --- a/modules/luci-mod-system/luasrc/controller/admin/system.lua +++ b/modules/luci-mod-system/luasrc/controller/admin/system.lua @@ -10,7 +10,16 @@ function index() entry({"admin", "system", "system"}, cbi("admin_system/system"), _("System"), 1) entry({"admin", "system", "clock_status"}, post_on({ set = true }, "action_clock_status")) - entry({"admin", "system", "admin"}, cbi("admin_system/admin"), _("Administration"), 2) + entry({"admin", "system", "admin"}, firstchild(), _("Administration"), 2) + entry({"admin", "system", "admin", "password"}, template("admin_system/password"), _("Router Password"), 1) + entry({"admin", "system", "admin", "password", "json"}, post("action_password")) + + if fs.access("/etc/config/dropbear") then + entry({"admin", "system", "admin", "dropbear"}, cbi("admin_system/dropbear"), _("SSH Access"), 2) + entry({"admin", "system", "admin", "sshkeys"}, template("admin_system/sshkeys"), _("SSH-Keys"), 3) + entry({"admin", "system", "admin", "sshkeys", "json"}, post_on({ keys = true }, "action_sshkeys")) + end + entry({"admin", "system", "startup"}, form("admin_system/startup"), _("Startup"), 45) entry({"admin", "system", "crontab"}, form("admin_system/crontab"), _("Scheduled Tasks"), 46) @@ -264,20 +273,65 @@ function action_reset() http.redirect(luci.dispatcher.build_url('admin/system/flashops')) end -function action_passwd() - local p1 = luci.http.formvalue("pwd1") - local p2 = luci.http.formvalue("pwd2") - local stat = nil +function action_password() + local password = luci.http.formvalue("password") + if not password then + luci.http.status(400, "Bad Request") + return + end - if p1 or p2 then - if p1 == p2 then - stat = luci.sys.user.setpasswd("root", p1) - else - stat = 10 + luci.http.prepare_content("application/json") + luci.http.write_json({ code = luci.sys.user.setpasswd("root", password) }) +end + +function action_sshkeys() + local keys = luci.http.formvalue("keys") + if keys then + keys = luci.jsonc.parse(keys) + if not keys or type(keys) ~= "table" then + luci.http.status(400, "Bad Request") + return end + + local fd, err = io.open("/etc/dropbear/authorized_keys", "w") + if not fd then + luci.http.status(503, err) + return + end + + local _, k + for _, k in ipairs(keys) do + if type(k) == "string" and k:match("^%w+%-") then + fd:write(k) + fd:write("\n") + end + end + + fd:close() + end + + local fd, err = io.open("/etc/dropbear/authorized_keys", "r") + if not fd then + luci.http.status(503, err) + return end - luci.template.render("admin_system/passwd", {stat=stat}) + local rv = {} + while true do + local ln = fd:read("*l") + if not ln then + break + elseif ln:match("^[%w%-]+%s+[A-Za-z0-9+/=]+$") or + ln:match("^[%w%-]+%s+[A-Za-z0-9+/=]+%s") + then + rv[#rv+1] = ln + end + end + + fd:close() + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) end function action_reboot() diff --git a/modules/luci-mod-system/luasrc/model/cbi/admin_system/admin.lua b/modules/luci-mod-system/luasrc/model/cbi/admin_system/admin.lua deleted file mode 100644 index 34289533b..000000000 --- a/modules/luci-mod-system/luasrc/model/cbi/admin_system/admin.lua +++ /dev/null @@ -1,124 +0,0 @@ --- Copyright 2008 Steven Barth --- Copyright 2011 Jo-Philipp Wich --- Licensed to the public under the Apache License 2.0. - -local fs = require "nixio.fs" - -m = Map("system", translate("Router Password"), - translate("Changes the administrator password for accessing the device")) -m.apply_on_parse = true - -s = m:section(TypedSection, "_dummy", "") -s.addremove = false -s.anonymous = true - -pw1 = s:option(Value, "pw1", translate("Password")) -pw1.password = true - -pw2 = s:option(Value, "pw2", translate("Confirmation")) -pw2.password = true - -function s.cfgsections() - return { "_pass" } -end - -function m.parse(map) - local v1 = pw1:formvalue("_pass") - local v2 = pw2:formvalue("_pass") - - if v1 and v2 and #v1 > 0 and #v2 > 0 then - if v1 == v2 then - if luci.sys.user.setpasswd(luci.dispatcher.context.authuser, v1) == 0 then - m.message = translate("Password successfully changed!") - else - m.message = translate("Unknown Error, password not changed!") - end - else - m.message = translate("Given password confirmation did not match, password not changed!") - end - end - - Map.parse(map) -end - - -if fs.access("/etc/config/dropbear") then - -m2 = Map("dropbear", translate("SSH Access"), - translate("Dropbear offers SSH network shell access and an integrated SCP server")) -m2.apply_on_parse = true - -s = m2:section(TypedSection, "dropbear", translate("Dropbear Instance")) -s.anonymous = true -s.addremove = true - - -ni = s:option(Value, "Interface", translate("Interface"), - translate("Listen only on the given interface or, if unspecified, on all")) - -ni.template = "cbi/network_netlist" -ni.nocreate = true -ni.unspecified = true - - -pt = s:option(Value, "Port", translate("Port"), - translate("Specifies the listening port of this Dropbear instance")) - -pt.datatype = "port" -pt.default = 22 - - -pa = s:option(Flag, "PasswordAuth", translate("Password authentication"), - translate("Allow SSH password authentication")) - -pa.enabled = "on" -pa.disabled = "off" -pa.default = pa.enabled -pa.rmempty = false - - -ra = s:option(Flag, "RootPasswordAuth", translate("Allow root logins with password"), - translate("Allow the root user to login with password")) - -ra.enabled = "on" -ra.disabled = "off" -ra.default = ra.enabled - - -gp = s:option(Flag, "GatewayPorts", translate("Gateway ports"), - translate("Allow remote hosts to connect to local SSH forwarded ports")) - -gp.enabled = "on" -gp.disabled = "off" -gp.default = gp.disabled - - -s2 = m2:section(TypedSection, "_dummy", translate("SSH-Keys"), - translate("Here you can paste public SSH-Keys (one per line) for SSH public-key authentication.")) -s2.addremove = false -s2.anonymous = true -s2.template = "cbi/tblsection" - -function s2.cfgsections() - return { "_keys" } -end - -keys = s2:option(TextValue, "_data", "") -keys.wrap = "off" -keys.rows = 3 - -function keys.cfgvalue() - return fs.readfile("/etc/dropbear/authorized_keys") or "" -end - -function keys.write(self, section, value) - return fs.writefile("/etc/dropbear/authorized_keys", value:gsub("\r\n", "\n")) -end - -function keys.remove(self, section, value) - return fs.writefile("/etc/dropbear/authorized_keys", "") -end - -end - -return m, m2 diff --git a/modules/luci-mod-system/luasrc/model/cbi/admin_system/dropbear.lua b/modules/luci-mod-system/luasrc/model/cbi/admin_system/dropbear.lua new file mode 100644 index 000000000..1a1695d2b --- /dev/null +++ b/modules/luci-mod-system/luasrc/model/cbi/admin_system/dropbear.lua @@ -0,0 +1,53 @@ +-- Copyright 2008 Steven Barth +-- Copyright 2011-2018 Jo-Philipp Wich +-- Licensed to the public under the Apache License 2.0. + +m = Map("dropbear", translate("SSH Access"), + translate("Dropbear offers SSH network shell access and an integrated SCP server")) +m.apply_on_parse = true + +s = m:section(TypedSection, "dropbear", translate("Dropbear Instance")) +s.anonymous = true +s.addremove = true + + +ni = s:option(Value, "Interface", translate("Interface"), + translate("Listen only on the given interface or, if unspecified, on all")) + +ni.template = "cbi/network_netlist" +ni.nocreate = true +ni.unspecified = true + + +pt = s:option(Value, "Port", translate("Port"), + translate("Specifies the listening port of this Dropbear instance")) + +pt.datatype = "port" +pt.default = 22 + + +pa = s:option(Flag, "PasswordAuth", translate("Password authentication"), + translate("Allow SSH password authentication")) + +pa.enabled = "on" +pa.disabled = "off" +pa.default = pa.enabled +pa.rmempty = false + + +ra = s:option(Flag, "RootPasswordAuth", translate("Allow root logins with password"), + translate("Allow the root user to login with password")) + +ra.enabled = "on" +ra.disabled = "off" +ra.default = ra.enabled + + +gp = s:option(Flag, "GatewayPorts", translate("Gateway ports"), + translate("Allow remote hosts to connect to local SSH forwarded ports")) + +gp.enabled = "on" +gp.disabled = "off" +gp.default = gp.disabled + +return m diff --git a/modules/luci-mod-system/luasrc/view/admin_system/password.htm b/modules/luci-mod-system/luasrc/view/admin_system/password.htm new file mode 100644 index 000000000..3aff9c981 --- /dev/null +++ b/modules/luci-mod-system/luasrc/view/admin_system/password.htm @@ -0,0 +1,70 @@ +<%+header%> + + + + + +
+

<%:Router Password%>

+ +
+ <%:Changes the administrator password for accessing the device%> +
+ +
+
+ +
+ +
+
+ +
+ +
+ +
+
+
+
+ +
+ +
+ +<%+footer%> diff --git a/modules/luci-mod-system/luasrc/view/admin_system/sshkeys.htm b/modules/luci-mod-system/luasrc/view/admin_system/sshkeys.htm new file mode 100644 index 000000000..acf008adf --- /dev/null +++ b/modules/luci-mod-system/luasrc/view/admin_system/sshkeys.htm @@ -0,0 +1,245 @@ +<%+header%> + + + + + +
+

<%:SSH-Keys%>

+ +
+ <%_Public keys allow for the passwordless SSH logins with a higher security compared to the use of plain passwords. In order to upload a new key to the device, paste an OpenSSH compatible public key line or drag a .pub file into the input field.%> +
+ +
+
+

<%:Loading SSH keys…%>

+
+
<%:Add key%>
+
+
+
+
+ +<%+footer%> -- 2.25.1