summaryrefslogtreecommitdiffhomepage
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/luci-base/htdocs/luci-static/resources/firewall.js8
-rw-r--r--modules/luci-base/htdocs/luci-static/resources/tools/widgets.js157
-rwxr-xr-xmodules/luci-base/root/usr/libexec/rpcd/luci35
-rw-r--r--modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json14
4 files changed, 203 insertions, 11 deletions
diff --git a/modules/luci-base/htdocs/luci-static/resources/firewall.js b/modules/luci-base/htdocs/luci-static/resources/firewall.js
index d034d6e010..9ae14e16d9 100644
--- a/modules/luci-base/htdocs/luci-static/resources/firewall.js
+++ b/modules/luci-base/htdocs/luci-static/resources/firewall.js
@@ -375,6 +375,14 @@ Zone = AbstractFirewallItem.extend({
this.set('network', ' ');
},
+ getDevices: function() {
+ return L.toArray(this.get('device'));
+ },
+
+ getSubnets: function() {
+ return L.toArray(this.get('subnet'));
+ },
+
getForwardingsBy: function(what) {
var sections = uci.sections('firewall', 'forwarding'),
forwards = [];
diff --git a/modules/luci-base/htdocs/luci-static/resources/tools/widgets.js b/modules/luci-base/htdocs/luci-static/resources/tools/widgets.js
index 3de1f8258e..39e5aa1655 100644
--- a/modules/luci-base/htdocs/luci-static/resources/tools/widgets.js
+++ b/modules/luci-base/htdocs/luci-static/resources/tools/widgets.js
@@ -199,10 +199,16 @@ var CBIZoneForwards = form.DummyValue.extend({
__name__: 'CBI.ZoneForwards',
load: function(section_id) {
- return Promise.all([ firewall.getDefaults(), firewall.getZones(), network.getNetworks() ]).then(L.bind(function(dzn) {
- this.defaults = dzn[0];
- this.zones = dzn[1];
- this.networks = dzn[2];
+ return Promise.all([
+ firewall.getDefaults(),
+ firewall.getZones(),
+ network.getNetworks(),
+ network.getDevices()
+ ]).then(L.bind(function(dznd) {
+ this.defaults = dznd[0];
+ this.zones = dznd[1];
+ this.networks = dznd[2];
+ this.devices = dznd[3];
return this.super('load', section_id);
}, this));
@@ -211,6 +217,8 @@ var CBIZoneForwards = form.DummyValue.extend({
renderZone: function(zone) {
var name = zone.getName(),
networks = zone.getNetworks(),
+ devices = zone.getDevices(),
+ subnets = zone.getSubnets(),
ifaces = [];
for (var j = 0; j < networks.length; j++) {
@@ -223,21 +231,39 @@ var CBIZoneForwards = form.DummyValue.extend({
'class': 'ifacebadge' + (network.getName() == this.network ? ' ifacebadge-active' : '')
}, network.getName() + ': ');
- var devices = network.isBridge() ? network.getDevices() : L.toArray(network.getDevice());
+ var subdevs = network.isBridge() ? network.getDevices() : L.toArray(network.getDevice());
- for (var k = 0; k < devices.length && devices[k]; k++) {
+ for (var k = 0; k < subdevs.length && subdevs[k]; k++) {
span.appendChild(E('img', {
- 'title': devices[k].getI18n(),
- 'src': L.resource('icons/%s%s.png'.format(devices[k].getType(), devices[k].isUp() ? '' : '_disabled'))
+ 'title': subdevs[k].getI18n(),
+ 'src': L.resource('icons/%s%s.png'.format(subdevs[k].getType(), subdevs[k].isUp() ? '' : '_disabled'))
}));
}
- if (!devices.length)
+ if (!subdevs.length)
span.appendChild(E('em', _('(empty)')));
ifaces.push(span);
}
+ for (var i = 0; i < devices.length; i++) {
+ var device = this.devices.filter(function(dev) { return dev.getName() == devices[i] })[0],
+ title = device ? device.getI18n() : _('Absent Interface'),
+ type = device ? device.getType() : 'ethernet',
+ up = device ? device.isUp() : false;
+
+ ifaces.push(E('span', { 'class': 'ifacebadge' }, [
+ E('img', {
+ 'title': title,
+ 'src': L.resource('icons/%s%s.png'.format(type, up ? '' : '_disabled'))
+ }),
+ device ? device.getName() : devices[i]
+ ]));
+ }
+
+ if (subnets.length > 0)
+ ifaces.push(E('span', { 'class': 'ifacebadge' }, [ '{ %s }'.format(subnets.join('; ')) ]));
+
if (!ifaces.length)
ifaces.push(E('span', { 'class': 'ifacebadge' }, E('em', _('(empty)'))));
@@ -390,9 +416,120 @@ var CBINetworkSelect = form.ListValue.extend({
},
});
+var CBIDeviceSelect = form.ListValue.extend({
+ __name__: 'CBI.DeviceSelect',
+
+ load: function(section_id) {
+ return network.getDevices().then(L.bind(function(devices) {
+ this.devices = devices;
+
+ return this.super('load', section_id);
+ }, this));
+ },
+
+ filter: function(section_id, value) {
+ return true;
+ },
+
+ renderWidget: function(section_id, option_index, cfgvalue) {
+ var values = L.toArray((cfgvalue != null) ? cfgvalue : this.default),
+ choices = {},
+ checked = {},
+ order = [];
+
+ for (var i = 0; i < values.length; i++)
+ checked[values[i]] = true;
+
+ values = [];
+
+ if (!this.multiple && (this.rmempty || this.optional))
+ choices[''] = E('em', _('unspecified'));
+
+ for (var i = 0; i < this.devices.length; i++) {
+ var device = this.devices[i],
+ name = device.getName(),
+ type = device.getType();
+
+ if (name == 'lo' || name == this.exclude || !this.filter(section_id, name))
+ continue;
+
+ if (this.noaliases && type == 'alias')
+ continue;
+
+ if (this.nobridges && type == 'bridge')
+ continue;
+
+ if (this.noinactive && device.isUp() == false)
+ continue;
+
+ var item = E([
+ E('img', {
+ 'title': device.getI18n(),
+ 'src': L.resource('icons/%s%s.png'.format(type, device.isUp() ? '' : '_disabled'))
+ }),
+ E('span', { 'class': 'hide-open' }, [ name ]),
+ E('span', { 'class': 'hide-close'}, [ device.getI18n() ])
+ ]);
+
+ var networks = device.getNetworks();
+
+ if (networks.length > 0)
+ L.dom.append(item.lastChild, [ ' (', networks.join(', '), ')' ]);
+
+ if (checked[name])
+ values.push(name);
+
+ choices[name] = item;
+ order.push(name);
+ }
+
+ if (!this.nocreate) {
+ var keys = Object.keys(checked).sort();
+
+ for (var i = 0; i < keys.length; i++) {
+ if (choices.hasOwnProperty(keys[i]))
+ continue;
+
+ choices[keys[i]] = E([
+ E('img', {
+ 'title': _('Absent Interface'),
+ 'src': L.resource('icons/ethernet_disabled.png')
+ }),
+ E('span', { 'class': 'hide-open' }, [ keys[i] ]),
+ E('span', { 'class': 'hide-close'}, [ '%s: "%h"'.format(_('Absent Interface'), keys[i]) ])
+ ]);
+
+ values.push(keys[i]);
+ order.push(keys[i]);
+ }
+ }
+
+ var widget = new ui.Dropdown(this.multiple ? values : values[0], choices, {
+ id: this.cbid(section_id),
+ sort: order,
+ multiple: this.multiple,
+ optional: this.optional || this.rmempty,
+ select_placeholder: E('em', _('unspecified')),
+ display_items: this.display_size || this.size || 3,
+ dropdown_items: this.dropdown_size || this.size || 5,
+ validate: L.bind(this.validate, this, section_id),
+ create: !this.nocreate,
+ create_markup: '' +
+ '<li data-value="{{value}}">' +
+ '<img title="'+_('Custom Interface')+': &quot;{{value}}&quot;" src="'+L.resource('icons/ethernet_disabled.png')+'" />' +
+ '<span class="hide-open">{{value}}</span>' +
+ '<span class="hide-close">'+_('Custom Interface')+': "{{value}}"</span>' +
+ '</li>'
+ });
+
+ return widget.render();
+ },
+});
+
return L.Class.extend({
ZoneSelect: CBIZoneSelect,
ZoneForwards: CBIZoneForwards,
- NetworkSelect: CBINetworkSelect
+ NetworkSelect: CBINetworkSelect,
+ DeviceSelect: CBIDeviceSelect,
});
diff --git a/modules/luci-base/root/usr/libexec/rpcd/luci b/modules/luci-base/root/usr/libexec/rpcd/luci
index 55233d6d0a..7644745efd 100755
--- a/modules/luci-base/root/usr/libexec/rpcd/luci
+++ b/modules/luci-base/root/usr/libexec/rpcd/luci
@@ -285,6 +285,41 @@ local methods = {
local fs = require "nixio.fs"
return { offload_support = not not fs.access("/sys/module/xt_FLOWOFFLOAD/refcnt") }
end
+ },
+
+ conntrack_helpers = {
+ call = function()
+ local fd = io.open("/usr/share/fw3/helpers.conf", "r")
+ local rv = {}
+
+ local line, entry
+ while true do
+ line = fd:read("*l")
+ if not line then
+ break
+ end
+
+ if line:match("^%s*config%s") then
+ if entry then
+ rv[#rv+1] = entry
+ end
+ entry = {}
+ else
+ local opt, val = line:match("^%s*option%s+(%S+)%s+(%S.*)$")
+ if opt and val then
+ opt = opt:gsub("^'(.+)'$", "%1"):gsub('^"(.+)"$', "%1")
+ val = val:gsub("^'(.+)'$", "%1"):gsub('^"(.+)"$', "%1")
+ entry[opt] = val
+ end
+ end
+ end
+
+ if entry then
+ rv[#rv+1] = entry
+ end
+
+ return { helpers = rv }
+ 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 a9baef8f9c..de145ce784 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
@@ -13,7 +13,7 @@
"read": {
"ubus": {
"iwinfo": [ "info" ],
- "luci": [ "boardjson", "duid_hints", "host_hints", "ifaddrs", "initList", "getLocaltime", "leases", "leds", "netdevs", "offload_support", "usb" ],
+ "luci": [ "boardjson", "duid_hints", "host_hints", "ifaddrs", "initList", "getLocaltime", "leases", "leds", "netdevs", "usb" ],
"network.device": [ "status" ],
"network.interface": [ "dump" ],
"network.wireless": [ "status" ],
@@ -28,5 +28,17 @@
},
"uci": [ "*" ]
}
+ },
+ "luci-app-firewall": {
+ "description": "Grant access to firewall procedures",
+ "read": {
+ "ubus": {
+ "luci": [ "conntrack_helpers", "offload_support" ]
+ },
+ "uci": [ "firewall" ]
+ },
+ "write": {
+ "uci": [ "firewall" ]
+ }
}
}