From: Jo-Philipp Wich Date: Sun, 3 Nov 2019 19:34:57 +0000 (+0100) Subject: luci-base, luci-app-firewall: port custom rules to client side view X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=9e57fbb2c3f9c44cdf0a57e6fb9c1df32c84d52b;p=oweals%2Fluci.git luci-base, luci-app-firewall: port custom rules to client side view Signed-off-by: Jo-Philipp Wich --- diff --git a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/custom.js b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/custom.js new file mode 100644 index 000000000..4b4b14008 --- /dev/null +++ b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/custom.js @@ -0,0 +1,31 @@ +'use strict'; +'require fs'; + +return L.view.extend({ + load: function() { + return L.resolveDefault(fs.read('/etc/firewall.user'), ''); + }, + + handleSave: function(ev) { + var value = (document.querySelector('textarea').value || '').trim().replace(/\r\n/g, '\n') + '\n'; + + return fs.write('/etc/firewall.user', value).then(function(rc) { + document.querySelector('textarea').value = value; + L.ui.addNotification(null, E('p', _('Contents have been saved.')), 'info'); + fs.exec('/etc/init.d/firewall', ['restart']); + }).catch(function(e) { + L.ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message))); + }); + }, + + render: function(fwuser) { + return E([ + E('h2', _('Firewall - Custom Rules')), + E('p', {}, _('Custom rules allow you to execute arbitrary iptables commands which are not otherwise covered by the firewall framework. The commands are executed after each firewall restart, right after the default ruleset has been loaded.')), + E('p', {}, E('textarea', { 'style': 'width:100%', 'rows': 10 }, [ fwuser != null ? fwuser : '' ])) + ]); + }, + + handleSaveApply: null, + handleReset: null +}); diff --git a/applications/luci-app-firewall/luasrc/controller/firewall.lua b/applications/luci-app-firewall/luasrc/controller/firewall.lua index 58a44c601..5f8cb6ef3 100644 --- a/applications/luci-app-firewall/luasrc/controller/firewall.lua +++ b/applications/luci-app-firewall/luasrc/controller/firewall.lua @@ -15,6 +15,5 @@ function index() view("firewall/rules"), _("Traffic Rules"), 30) entry({"admin", "network", "firewall", "custom"}, - form("firewall/custom"), - _("Custom Rules"), 40).leaf = true + view("firewall/custom"), _("Custom Rules"), 40).leaf = true end diff --git a/applications/luci-app-firewall/luasrc/model/cbi/firewall/custom.lua b/applications/luci-app-firewall/luasrc/model/cbi/firewall/custom.lua deleted file mode 100644 index 21a1b2796..000000000 --- a/applications/luci-app-firewall/luasrc/model/cbi/firewall/custom.lua +++ /dev/null @@ -1,31 +0,0 @@ --- Copyright 2011 Jo-Philipp Wich --- Licensed to the public under the Apache License 2.0. - -local fs = require "nixio.fs" - -local f = SimpleForm("firewall", - translate("Firewall - Custom Rules"), - translate("Custom rules allow you to execute arbitrary iptables commands \ - which are not otherwise covered by the firewall framework. \ - The commands are executed after each firewall restart, right after \ - the default ruleset has been loaded.")) - -local o = f:field(Value, "_custom") - -o.template = "cbi/tvalue" -o.rows = 20 - -function o.cfgvalue(self, section) - return fs.readfile("/etc/firewall.user") -end - -function o.write(self, section, value) - value = value:gsub("\r\n?", "\n") - fs.writefile("/etc/firewall.user", value) - require("luci.sys").call("/etc/init.d/firewall restart >/dev/null 2<&1") - require("nixio").syslog('info', 'Restarting firewall on custom /etc/firewall.user change') -end - -f.submit = translate("Restart Firewall") - -return f diff --git a/applications/luci-app-firewall/luasrc/tools/firewall.lua b/applications/luci-app-firewall/luasrc/tools/firewall.lua deleted file mode 100644 index 055342bfb..000000000 --- a/applications/luci-app-firewall/luasrc/tools/firewall.lua +++ /dev/null @@ -1,289 +0,0 @@ --- Copyright 2011-2012 Jo-Philipp Wich --- Licensed to the public under the Apache License 2.0. - -module("luci.tools.firewall", package.seeall) - -local ut = require "luci.util" -local ip = require "luci.ip" -local nx = require "nixio" - -local translate, translatef = luci.i18n.translate, luci.i18n.translatef - -local function _(...) - return tostring(translate(...)) -end - -function fmt_neg(x) - if type(x) == "string" then - local v, neg = x:gsub("^ *! *", "") - if neg > 0 then - return v, "%s " % _("not") - else - return x, "" - end - end - return x, "" -end - -function fmt_mac(x) - if x and #x > 0 then - local m, n - local l = { _("MAC"), " " } - for m in ut.imatch(x) do - m, n = fmt_neg(m) - l[#l+1] = "%s%s" %{ n, m } - l[#l+1] = ", " - end - if #l > 1 then - l[#l] = nil - if #l > 3 then - l[1] = _("MACs") - end - return table.concat(l, "") - end - end -end - -function fmt_port(x, d) - if x and #x > 0 then - local p, n - local l = { _("port"), " " } - for p in ut.imatch(x) do - p, n = fmt_neg(p) - local a, b = p:match("(%d+)%D+(%d+)") - if a and b then - l[1] = _("ports") - l[#l+1] = "%s%d-%d" %{ n, a, b } - else - l[#l+1] = "%s%d" %{ n, p } - end - l[#l+1] = ", " - end - if #l > 1 then - l[#l] = nil - if #l > 3 then - l[1] = _("ports") - end - return table.concat(l, "") - end - end - return d and "%s" % d -end - -function fmt_ip(x, d) - if x and #x > 0 then - local l = { _("IP"), " " } - local v, a, n - for v in ut.imatch(x) do - v, n = fmt_neg(v) - a, m = v:match("(%S+)/(%d+%.%S+)") - a = a or v - a = a:match(":") and ip.IPv6(a, m) or ip.IPv4(a, m) - if a and (a:is6() and a:prefix() < 128 or a:prefix() < 32) then - l[1] = _("IP range") - l[#l+1] = "%s%s" %{ - a:minhost():string(), - a:maxhost():string(), - n, a:string() - } - else - l[#l+1] = "%s%s" %{ - n, - a and a:string() or v - } - end - l[#l+1] = ", " - end - if #l > 1 then - l[#l] = nil - if #l > 3 then - l[1] = _("IPs") - end - return table.concat(l, "") - end - end - return d and "%s" % d -end - -function fmt_zone(x, d) - if x == "*" then - return "%s" % _("any zone") - elseif x and #x > 0 then - return "%s" % x - elseif d then - return "%s" % d - end -end - -function fmt_icmp_type(x) - if x and #x > 0 then - local t, v, n - local l = { _("type"), " " } - for v in ut.imatch(x) do - v, n = fmt_neg(v) - l[#l+1] = "%s%s" %{ n, v } - l[#l+1] = ", " - end - if #l > 1 then - l[#l] = nil - if #l > 3 then - l[1] = _("types") - end - return table.concat(l, "") - end - end -end - -function fmt_proto(x, icmp_types) - if x and #x > 0 then - local v, n - local l = { } - local t = fmt_icmp_type(icmp_types) - for v in ut.imatch(x) do - v, n = fmt_neg(v) - if v == "tcpudp" then - l[#l+1] = "TCP" - l[#l+1] = ", " - l[#l+1] = "UDP" - l[#l+1] = ", " - elseif v ~= "all" then - local p = nx.getproto(v) - if p then - -- ICMP - if (p.proto == 1 or p.proto == 58) and t then - l[#l+1] = translatef( - "%s%s with %s", - n, p.aliases[1] or p.name, t - ) - else - l[#l+1] = "%s%s" %{ - n, - p.aliases[1] or p.name - } - end - l[#l+1] = ", " - end - end - end - if #l > 0 then - l[#l] = nil - return table.concat(l, "") - end - end -end - -function fmt_limit(limit, burst) - burst = tonumber(burst) - if limit and #limit > 0 then - local l, u = limit:match("(%d+)/(%w+)") - l = tonumber(l or limit) - u = u or "second" - if l then - if u:match("^s") then - u = _("second") - elseif u:match("^m") then - u = _("minute") - elseif u:match("^h") then - u = _("hour") - elseif u:match("^d") then - u = _("day") - end - if burst and burst > 0 then - return translatef("%d pkts. per %s, \ - burst %d pkts.", l, u, burst) - else - return translatef("%d pkts. per %s", l, u) - end - end - end -end - -function fmt_target(x, src, dest) - if not src or #src == 0 then - if x == "ACCEPT" then - return _("Accept output") - elseif x == "REJECT" then - return _("Refuse output") - elseif x == "NOTRACK" then - return _("Do not track output") - else --if x == "DROP" then - return _("Discard output") - end - elseif dest and #dest > 0 then - if x == "ACCEPT" then - return _("Accept forward") - elseif x == "REJECT" then - return _("Refuse forward") - elseif x == "NOTRACK" then - return _("Do not track forward") - else --if x == "DROP" then - return _("Discard forward") - end - else - if x == "ACCEPT" then - return _("Accept input") - elseif x == "REJECT" then - return _("Refuse input") - elseif x == "NOTRACK" then - return _("Do not track input") - else --if x == "DROP" then - return _("Discard input") - end - end -end - - -function opt_enabled(s, t, ...) - if t == luci.cbi.Button then - local o = s:option(t, "__enabled") - function o.render(self, section) - if self.map:get(section, "enabled") ~= "0" then - self.title = _("Rule is enabled") - self.inputtitle = _("Disable") - self.inputstyle = "reset" - else - self.title = _("Rule is disabled") - self.inputtitle = _("Enable") - self.inputstyle = "apply" - end - t.render(self, section) - end - function o.write(self, section, value) - if self.map:get(section, "enabled") ~= "0" then - self.map:set(section, "enabled", "0") - else - self.map:del(section, "enabled") - end - end - return o - else - local o = s:option(t, "enabled", ...) - o.default = "1" - return o - end -end - -function opt_name(s, t, ...) - local o = s:option(t, "name", ...) - - function o.cfgvalue(self, section) - return self.map:get(section, "name") or - self.map:get(section, "_name") or "-" - end - - function o.write(self, section, value) - if value ~= "-" then - self.map:set(section, "name", value) - self.map:del(section, "_name") - else - self:remove(section) - end - end - - function o.remove(self, section) - self.map:del(section, "name") - self.map:del(section, "_name") - end - - return o -end diff --git a/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json b/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json index a60c432bc..321817302 100644 --- a/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json +++ b/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json @@ -88,12 +88,19 @@ "luci-app-firewall": { "description": "Grant access to firewall procedures", "read": { + "file": { + "/etc/firewall.user": [ "read" ] + }, "ubus": { "luci": [ "getConntrackHelpers" ] }, "uci": [ "firewall" ] }, "write": { + "file": { + "/etc/firewall.user": [ "write" ], + "/etc/init.d/firewall": [ "exec" ] + }, "uci": [ "firewall" ] } }