mirror of
https://github.com/Ysurac/openmptcprouter-feeds.git
synced 2025-02-14 19:41:51 +00:00
Update luci-mod-network
This commit is contained in:
parent
70d1670539
commit
33830e25d5
9 changed files with 747 additions and 291 deletions
|
@ -1,9 +1,10 @@
|
|||
#
|
||||
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
|
||||
# Copyright (C) 2020 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
# From https://github.com/openwrt/luci/commit/6efaea2ffb46f9909038b85cf12e7acf4467ae2e
|
||||
# From https://github.com/openwrt/luci/commit/1e07e3a52d4d06cc82ab07f2b7fbba0a9a6fb801
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
'use strict';
|
||||
'require view';
|
||||
'require dom';
|
||||
'require poll';
|
||||
'require rpc';
|
||||
'require uci';
|
||||
'require form';
|
||||
|
@ -123,7 +126,7 @@ function validateServerSpec(sid, s) {
|
|||
return true;
|
||||
}
|
||||
|
||||
return L.view.extend({
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
callHostHints(),
|
||||
|
@ -440,7 +443,7 @@ return L.view.extend({
|
|||
|
||||
var node = ipopt.map.findElement('id', ipopt.cbid(section_id));
|
||||
if (node)
|
||||
L.dom.callClassMethod(node, 'setValue', hosts[mac].ipv4);
|
||||
dom.callClassMethod(node, 'setValue', hosts[mac].ipv4);
|
||||
}, this, ipopt, section_id));
|
||||
|
||||
return node;
|
||||
|
@ -491,7 +494,7 @@ return L.view.extend({
|
|||
o = s.taboption('leases', CBILease6Status, '__status6__');
|
||||
|
||||
return m.render().then(function(mapEl) {
|
||||
L.Poll.add(function() {
|
||||
poll.add(function() {
|
||||
return callDHCPLeases().then(function(leaseinfo) {
|
||||
var leases = Array.isArray(leaseinfo.dhcp_leases) ? leaseinfo.dhcp_leases : [],
|
||||
leases6 = Array.isArray(leaseinfo.dhcp6_leases) ? leaseinfo.dhcp6_leases : [];
|
||||
|
|
|
@ -0,0 +1,556 @@
|
|||
'use strict';
|
||||
'require view';
|
||||
'require dom';
|
||||
'require poll';
|
||||
'require rpc';
|
||||
'require uci';
|
||||
'require form';
|
||||
'require validation';
|
||||
|
||||
var callHostHints, callDUIDHints, callDHCPLeases, CBILeaseStatus, CBILease6Status;
|
||||
|
||||
callHostHints = rpc.declare({
|
||||
object: 'luci-rpc',
|
||||
method: 'getHostHints',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
callDUIDHints = rpc.declare({
|
||||
object: 'luci-rpc',
|
||||
method: 'getDUIDHints',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
callDHCPLeases = rpc.declare({
|
||||
object: 'luci-rpc',
|
||||
method: 'getDHCPLeases',
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
CBILeaseStatus = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_id, cfgvalue) {
|
||||
return E([
|
||||
E('h4', _('Active DHCP Leases')),
|
||||
E('div', { 'id': 'lease_status_table', 'class': 'table' }, [
|
||||
E('div', { 'class': 'tr table-titles' }, [
|
||||
E('div', { 'class': 'th' }, _('Hostname')),
|
||||
E('div', { 'class': 'th' }, _('IPv4-Address')),
|
||||
E('div', { 'class': 'th' }, _('MAC-Address')),
|
||||
E('div', { 'class': 'th' }, _('Lease time remaining'))
|
||||
]),
|
||||
E('div', { 'class': 'tr placeholder' }, [
|
||||
E('div', { 'class': 'td' }, E('em', _('Collecting data...')))
|
||||
])
|
||||
])
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
CBILease6Status = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_id, cfgvalue) {
|
||||
return E([
|
||||
E('h4', _('Active DHCPv6 Leases')),
|
||||
E('div', { 'id': 'lease6_status_table', 'class': 'table' }, [
|
||||
E('div', { 'class': 'tr table-titles' }, [
|
||||
E('div', { 'class': 'th' }, _('Host')),
|
||||
E('div', { 'class': 'th' }, _('IPv6-Address')),
|
||||
E('div', { 'class': 'th' }, _('DUID')),
|
||||
E('div', { 'class': 'th' }, _('Lease time remaining'))
|
||||
]),
|
||||
E('div', { 'class': 'tr placeholder' }, [
|
||||
E('div', { 'class': 'td' }, E('em', _('Collecting data...')))
|
||||
])
|
||||
])
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
function validateHostname(sid, s) {
|
||||
if (s.length > 256)
|
||||
return _('Expecting: %s').format(_('valid hostname'));
|
||||
|
||||
var labels = s.replace(/^\.+|\.$/g, '').split(/\./);
|
||||
|
||||
for (var i = 0; i < labels.length; i++)
|
||||
if (!labels[i].match(/^[a-z0-9_](?:[a-z0-9-]{0,61}[a-z0-9])?$/i))
|
||||
return _('Expecting: %s').format(_('valid hostname'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateAddressList(sid, s) {
|
||||
if (s == null || s == '')
|
||||
return true;
|
||||
|
||||
var m = s.match(/^\/(.+)\/$/),
|
||||
names = m ? m[1].split(/\//) : [ s ];
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
var res = validateHostname(sid, names[i]);
|
||||
|
||||
if (res !== true)
|
||||
return res;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateServerSpec(sid, s) {
|
||||
if (s == null || s == '')
|
||||
return true;
|
||||
|
||||
var m = s.match(/^\/(.+)\/(.*)$/);
|
||||
if (!m)
|
||||
return _('Expecting: %s').format(_('valid hostname'));
|
||||
|
||||
var res = validateAddressList(sid, m[1]);
|
||||
if (res !== true)
|
||||
return res;
|
||||
|
||||
if (m[2] == '' || m[2] == '#')
|
||||
return true;
|
||||
|
||||
// ipaddr%scopeid#srvport@source@interface#srcport
|
||||
|
||||
m = m[2].match(/^([0-9a-f:.]+)(?:%[^#@]+)?(?:#(\d+))?(?:@([0-9a-f:.]+)(?:@[^#]+)?(?:#(\d+))?)?$/);
|
||||
|
||||
if (!m)
|
||||
return _('Expecting: %s').format(_('valid IP address'));
|
||||
else if (validation.parseIPv4(m[1]) && m[3] != null && !validation.parseIPv4(m[3]))
|
||||
return _('Expecting: %s').format(_('valid IPv4 address'));
|
||||
else if (validation.parseIPv6(m[1]) && m[3] != null && !validation.parseIPv6(m[3]))
|
||||
return _('Expecting: %s').format(_('valid IPv6 address'));
|
||||
else if ((m[2] != null && +m[2] > 65535) || (m[4] != null && +m[4] > 65535))
|
||||
return _('Expecting: %s').format(_('valid port value'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
callHostHints(),
|
||||
callDUIDHints()
|
||||
]);
|
||||
},
|
||||
|
||||
render: function(hosts_duids) {
|
||||
var has_dhcpv6 = L.hasSystemFeature('dnsmasq', 'dhcpv6') || L.hasSystemFeature('odhcpd'),
|
||||
hosts = hosts_duids[0],
|
||||
duids = hosts_duids[1],
|
||||
m, s, o, ss, so;
|
||||
|
||||
m = new form.Map('dhcp', _('DHCP and DNS'), _('Dnsmasq is a combined <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-Server and <abbr title="Domain Name System">DNS</abbr>-Forwarder for <abbr title="Network Address Translation">NAT</abbr> firewalls'));
|
||||
|
||||
s = m.section(form.TypedSection, 'dnsmasq', _('Server Settings'));
|
||||
s.anonymous = true;
|
||||
s.addremove = false;
|
||||
|
||||
s.tab('general', _('General Settings'));
|
||||
s.tab('files', _('Resolv and Hosts Files'));
|
||||
s.tab('tftp', _('TFTP Settings'));
|
||||
s.tab('advanced', _('Advanced Settings'));
|
||||
s.tab('leases', _('Static Leases'));
|
||||
|
||||
s.taboption('general', form.Flag, 'domainneeded',
|
||||
_('Domain required'),
|
||||
_('Don\'t forward <abbr title="Domain Name System">DNS</abbr>-Requests without <abbr title="Domain Name System">DNS</abbr>-Name'));
|
||||
|
||||
s.taboption('general', form.Flag, 'authoritative',
|
||||
_('Authoritative'),
|
||||
_('This is the only <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr> in the local network'));
|
||||
|
||||
|
||||
s.taboption('files', form.Flag, 'readethers',
|
||||
_('Use <code>/etc/ethers</code>'),
|
||||
_('Read <code>/etc/ethers</code> to configure the <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-Server'));
|
||||
|
||||
s.taboption('files', form.Value, 'leasefile',
|
||||
_('Leasefile'),
|
||||
_('file where given <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr>-leases will be stored'));
|
||||
|
||||
s.taboption('files', form.Flag, 'noresolv',
|
||||
_('Ignore resolve file')).optional = true;
|
||||
|
||||
o = s.taboption('files', form.Value, 'resolvfile',
|
||||
_('Resolve file'),
|
||||
_('local <abbr title="Domain Name System">DNS</abbr> file'));
|
||||
|
||||
o.depends('noresolv', '0');
|
||||
o.placeholder = '/tmp/resolv.conf.d/resolv.conf.auto';
|
||||
o.optional = true;
|
||||
|
||||
|
||||
s.taboption('files', form.Flag, 'nohosts',
|
||||
_('Ignore <code>/etc/hosts</code>')).optional = true;
|
||||
|
||||
s.taboption('files', form.DynamicList, 'addnhosts',
|
||||
_('Additional Hosts files')).optional = true;
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'quietdhcp',
|
||||
_('Suppress logging'),
|
||||
_('Suppress logging of the routine operation of these protocols'));
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'sequential_ip',
|
||||
_('Allocate IP sequentially'),
|
||||
_('Allocate IP addresses sequentially, starting from the lowest available address'));
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'boguspriv',
|
||||
_('Filter private'),
|
||||
_('Do not forward reverse lookups for local networks'));
|
||||
o.default = o.enabled;
|
||||
|
||||
s.taboption('advanced', form.Flag, 'filterwin2k',
|
||||
_('Filter useless'),
|
||||
_('Do not forward requests that cannot be answered by public name servers'));
|
||||
|
||||
|
||||
s.taboption('advanced', form.Flag, 'localise_queries',
|
||||
_('Localise queries'),
|
||||
_('Localise hostname depending on the requesting subnet if multiple IPs are available'));
|
||||
|
||||
if (L.hasSystemFeature('dnsmasq', 'dnssec')) {
|
||||
o = s.taboption('advanced', form.Flag, 'dnssec',
|
||||
_('DNSSEC'));
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'dnsseccheckunsigned',
|
||||
_('DNSSEC check unsigned'),
|
||||
_('Requires upstream supports DNSSEC; verify unsigned domain responses really come from unsigned domains'));
|
||||
o.default = o.enabled;
|
||||
o.optional = true;
|
||||
}
|
||||
|
||||
s.taboption('general', form.Value, 'local',
|
||||
_('Local server'),
|
||||
_('Local domain specification. Names matching this domain are never forwarded and are resolved from DHCP or hosts files only'));
|
||||
|
||||
s.taboption('general', form.Value, 'domain',
|
||||
_('Local domain'),
|
||||
_('Local domain suffix appended to DHCP names and hosts file entries'));
|
||||
|
||||
s.taboption('advanced', form.Flag, 'expandhosts',
|
||||
_('Expand hosts'),
|
||||
_('Add local domain suffix to names served from hosts files'));
|
||||
|
||||
s.taboption('advanced', form.Flag, 'nonegcache',
|
||||
_('No negative cache'),
|
||||
_('Do not cache negative replies, e.g. for not existing domains'));
|
||||
|
||||
s.taboption('advanced', form.Value, 'serversfile',
|
||||
_('Additional servers file'),
|
||||
_('This file may contain lines like \'server=/domain/1.2.3.4\' or \'server=1.2.3.4\' for domain-specific or full upstream <abbr title="Domain Name System">DNS</abbr> servers.'));
|
||||
|
||||
s.taboption('advanced', form.Flag, 'strictorder',
|
||||
_('Strict order'),
|
||||
_('<abbr title="Domain Name System">DNS</abbr> servers will be queried in the order of the resolvfile')).optional = true;
|
||||
|
||||
s.taboption('advanced', form.Flag, 'allservers',
|
||||
_('All Servers'),
|
||||
_('Query all available upstream <abbr title="Domain Name System">DNS</abbr> servers')).optional = true;
|
||||
|
||||
o = s.taboption('advanced', form.DynamicList, 'bogusnxdomain', _('Bogus NX Domain Override'),
|
||||
_('List of hosts that supply bogus NX domain results'));
|
||||
|
||||
o.optional = true;
|
||||
o.placeholder = '67.215.65.132';
|
||||
|
||||
|
||||
s.taboption('general', form.Flag, 'logqueries',
|
||||
_('Log queries'),
|
||||
_('Write received DNS requests to syslog')).optional = true;
|
||||
|
||||
o = s.taboption('general', form.DynamicList, 'server', _('DNS forwardings'),
|
||||
_('List of <abbr title="Domain Name System">DNS</abbr> servers to forward requests to'));
|
||||
|
||||
o.optional = true;
|
||||
o.placeholder = '/example.org/10.1.2.3';
|
||||
o.validate = validateServerSpec;
|
||||
|
||||
|
||||
o = s.taboption('general', form.Flag, 'rebind_protection',
|
||||
_('Rebind protection'),
|
||||
_('Discard upstream RFC1918 responses'));
|
||||
|
||||
o.rmempty = false;
|
||||
|
||||
|
||||
o = s.taboption('general', form.Flag, 'rebind_localhost',
|
||||
_('Allow localhost'),
|
||||
_('Allow upstream responses in the 127.0.0.0/8 range, e.g. for RBL services'));
|
||||
|
||||
o.depends('rebind_protection', '1');
|
||||
|
||||
|
||||
o = s.taboption('general', form.DynamicList, 'rebind_domain',
|
||||
_('Domain whitelist'),
|
||||
_('List of domains to allow RFC1918 responses for'));
|
||||
o.optional = true;
|
||||
|
||||
o.depends('rebind_protection', '1');
|
||||
o.placeholder = 'ihost.netflix.com';
|
||||
o.validate = validateAddressList;
|
||||
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'port',
|
||||
_('<abbr title="Domain Name System">DNS</abbr> server port'),
|
||||
_('Listening port for inbound DNS queries'));
|
||||
|
||||
o.optional = true;
|
||||
o.datatype = 'port';
|
||||
o.placeholder = 53;
|
||||
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'queryport',
|
||||
_('<abbr title="Domain Name System">DNS</abbr> query port'),
|
||||
_('Fixed source port for outbound DNS queries'));
|
||||
|
||||
o.optional = true;
|
||||
o.datatype = 'port';
|
||||
o.placeholder = _('any');
|
||||
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'dhcpleasemax',
|
||||
_('<abbr title="maximal">Max.</abbr> <abbr title="Dynamic Host Configuration Protocol">DHCP</abbr> leases'),
|
||||
_('Maximum allowed number of active DHCP leases'));
|
||||
|
||||
o.optional = true;
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = _('unlimited');
|
||||
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'ednspacket_max',
|
||||
_('<abbr title="maximal">Max.</abbr> <abbr title="Extension Mechanisms for Domain Name System">EDNS0</abbr> packet size'),
|
||||
_('Maximum allowed size of EDNS.0 UDP packets'));
|
||||
|
||||
o.optional = true;
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = 1280;
|
||||
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'dnsforwardmax',
|
||||
_('<abbr title="maximal">Max.</abbr> concurrent queries'),
|
||||
_('Maximum allowed number of concurrent DNS queries'));
|
||||
|
||||
o.optional = true;
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = 150;
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'cachesize',
|
||||
_('Size of DNS query cache'),
|
||||
_('Number of cached DNS entries (max is 10000, 0 is no caching)'));
|
||||
o.optional = true;
|
||||
o.datatype = 'range(0,10000)';
|
||||
o.placeholder = 150;
|
||||
|
||||
s.taboption('tftp', form.Flag, 'enable_tftp',
|
||||
_('Enable TFTP server')).optional = true;
|
||||
|
||||
o = s.taboption('tftp', form.Value, 'tftp_root',
|
||||
_('TFTP server root'),
|
||||
_('Root directory for files served via TFTP'));
|
||||
|
||||
o.optional = true;
|
||||
o.depends('enable_tftp', '1');
|
||||
o.placeholder = '/';
|
||||
|
||||
|
||||
o = s.taboption('tftp', form.Value, 'dhcp_boot',
|
||||
_('Network boot image'),
|
||||
_('Filename of the boot image advertised to clients'));
|
||||
|
||||
o.optional = true;
|
||||
o.depends('enable_tftp', '1');
|
||||
o.placeholder = 'pxelinux.0';
|
||||
|
||||
o = s.taboption('general', form.Flag, 'localservice',
|
||||
_('Local Service Only'),
|
||||
_('Limit DNS service to subnets interfaces on which we are serving DNS.'));
|
||||
o.optional = false;
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('general', form.Flag, 'nonwildcard',
|
||||
_('Non-wildcard'),
|
||||
_('Bind dynamically to interfaces rather than wildcard address (recommended as linux default)'));
|
||||
o.default = o.enabled;
|
||||
o.optional = false;
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('general', form.DynamicList, 'interface',
|
||||
_('Listen Interfaces'),
|
||||
_('Limit listening to these interfaces, and loopback.'));
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('general', form.DynamicList, 'notinterface',
|
||||
_('Exclude interfaces'),
|
||||
_('Prevent listening on these interfaces.'));
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('leases', form.SectionValue, '__leases__', form.GridSection, 'host', null,
|
||||
_('Static leases are used to assign fixed IP addresses and symbolic hostnames to DHCP clients. They are also required for non-dynamic interface configurations where only hosts with a corresponding lease are served.') + '<br />' +
|
||||
_('Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> identifies the host, the <em>IPv4-Address</em> specifies the fixed address to use, and the <em>Hostname</em> is assigned as a symbolic name to the requesting host. The optional <em>Lease time</em> can be used to set non-standard host-specific lease time, e.g. 12h, 3d or infinite.'));
|
||||
|
||||
ss = o.subsection;
|
||||
|
||||
ss.addremove = true;
|
||||
ss.anonymous = true;
|
||||
|
||||
so = ss.option(form.Value, 'name', _('Hostname'));
|
||||
so.validate = validateHostname;
|
||||
so.rmempty = true;
|
||||
so.write = function(section, value) {
|
||||
uci.set('dhcp', section, 'name', value);
|
||||
uci.set('dhcp', section, 'dns', '1');
|
||||
};
|
||||
so.remove = function(section) {
|
||||
uci.unset('dhcp', section, 'name');
|
||||
uci.unset('dhcp', section, 'dns');
|
||||
};
|
||||
|
||||
so = ss.option(form.Value, 'mac', _('<abbr title="Media Access Control">MAC</abbr>-Address'));
|
||||
so.datatype = 'list(unique(macaddr))';
|
||||
so.rmempty = true;
|
||||
so.cfgvalue = function(section) {
|
||||
var macs = uci.get('dhcp', section, 'mac'),
|
||||
result = [];
|
||||
|
||||
if (!Array.isArray(macs))
|
||||
macs = (macs != null && macs != '') ? macs.split(/\ss+/) : [];
|
||||
|
||||
for (var i = 0, mac; (mac = macs[i]) != null; i++)
|
||||
if (/^([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2}):([0-9a-fA-F]{1,2})$/.test(mac))
|
||||
result.push('%02X:%02X:%02X:%02X:%02X:%02X'.format(
|
||||
parseInt(RegExp.$1, 16), parseInt(RegExp.$2, 16),
|
||||
parseInt(RegExp.$3, 16), parseInt(RegExp.$4, 16),
|
||||
parseInt(RegExp.$5, 16), parseInt(RegExp.$6, 16)));
|
||||
|
||||
return result.length ? result.join(' ') : null;
|
||||
};
|
||||
so.renderWidget = function(section_id, option_index, cfgvalue) {
|
||||
var node = form.Value.prototype.renderWidget.apply(this, [section_id, option_index, cfgvalue]),
|
||||
ipopt = this.section.children.filter(function(o) { return o.option == 'ip' })[0];
|
||||
|
||||
node.addEventListener('cbi-dropdown-change', L.bind(function(ipopt, section_id, ev) {
|
||||
var mac = ev.detail.value.value;
|
||||
if (mac == null || mac == '' || !hosts[mac] || !hosts[mac].ipv4)
|
||||
return;
|
||||
|
||||
var ip = ipopt.formvalue(section_id);
|
||||
if (ip != null && ip != '')
|
||||
return;
|
||||
|
||||
var node = ipopt.map.findElement('id', ipopt.cbid(section_id));
|
||||
if (node)
|
||||
dom.callClassMethod(node, 'setValue', hosts[mac].ipv4);
|
||||
}, this, ipopt, section_id));
|
||||
|
||||
return node;
|
||||
};
|
||||
Object.keys(hosts).forEach(function(mac) {
|
||||
var hint = hosts[mac].name || hosts[mac].ipv4;
|
||||
so.value(mac, hint ? '%s (%s)'.format(mac, hint) : mac);
|
||||
});
|
||||
|
||||
so = ss.option(form.Value, 'ip', _('<abbr title="Internet Protocol Version 4">IPv4</abbr>-Address'));
|
||||
so.datatype = 'or(ip4addr,"ignore")';
|
||||
so.validate = function(section, value) {
|
||||
var mac = this.map.lookupOption('mac', section),
|
||||
name = this.map.lookupOption('name', section),
|
||||
m = mac ? mac[0].formvalue(section) : null,
|
||||
n = name ? name[0].formvalue(section) : null;
|
||||
|
||||
if ((m == null || m == '') && (n == null || n == ''))
|
||||
return _('One of hostname or mac address must be specified!');
|
||||
|
||||
return true;
|
||||
};
|
||||
Object.keys(hosts).forEach(function(mac) {
|
||||
if (hosts[mac].ipv4) {
|
||||
var hint = hosts[mac].name;
|
||||
so.value(hosts[mac].ipv4, hint ? '%s (%s)'.format(hosts[mac].ipv4, hint) : hosts[mac].ipv4);
|
||||
}
|
||||
});
|
||||
|
||||
so = ss.option(form.Value, 'leasetime', _('Lease time'));
|
||||
so.rmempty = true;
|
||||
|
||||
so = ss.option(form.Value, 'duid', _('<abbr title="The DHCP Unique Identifier">DUID</abbr>'));
|
||||
so.datatype = 'and(rangelength(20,36),hexstring)';
|
||||
Object.keys(duids).forEach(function(duid) {
|
||||
so.value(duid, '%s (%s)'.format(duid, duids[duid].hostname || duids[duid].macaddr || duids[duid].ip6addr || '?'));
|
||||
});
|
||||
|
||||
so = ss.option(form.Value, 'hostid', _('<abbr title="Internet Protocol Version 6">IPv6</abbr>-Suffix (hex)'));
|
||||
|
||||
o = s.taboption('leases', CBILeaseStatus, '__status__');
|
||||
|
||||
if (has_dhcpv6)
|
||||
o = s.taboption('leases', CBILease6Status, '__status6__');
|
||||
|
||||
return m.render().then(function(mapEl) {
|
||||
poll.add(function() {
|
||||
return callDHCPLeases().then(function(leaseinfo) {
|
||||
var leases = Array.isArray(leaseinfo.dhcp_leases) ? leaseinfo.dhcp_leases : [],
|
||||
leases6 = Array.isArray(leaseinfo.dhcp6_leases) ? leaseinfo.dhcp6_leases : [];
|
||||
|
||||
cbi_update_table(mapEl.querySelector('#lease_status_table'),
|
||||
leases.map(function(lease) {
|
||||
var exp;
|
||||
|
||||
if (lease.expires === false)
|
||||
exp = E('em', _('unlimited'));
|
||||
else if (lease.expires <= 0)
|
||||
exp = E('em', _('expired'));
|
||||
else
|
||||
exp = '%t'.format(lease.expires);
|
||||
|
||||
return [
|
||||
lease.hostname || '?',
|
||||
lease.ipaddr,
|
||||
lease.macaddr,
|
||||
exp
|
||||
];
|
||||
}),
|
||||
E('em', _('There are no active leases')));
|
||||
|
||||
if (has_dhcpv6) {
|
||||
cbi_update_table(mapEl.querySelector('#lease6_status_table'),
|
||||
leases6.map(function(lease) {
|
||||
var exp;
|
||||
|
||||
if (lease.expires === false)
|
||||
exp = E('em', _('unlimited'));
|
||||
else if (lease.expires <= 0)
|
||||
exp = E('em', _('expired'));
|
||||
else
|
||||
exp = '%t'.format(lease.expires);
|
||||
|
||||
var hint = lease.macaddr ? hosts[lease.macaddr] : null,
|
||||
name = hint ? (hint.name || hint.ipv4 || hint.ipv6) : null,
|
||||
host = null;
|
||||
|
||||
if (name && lease.hostname && lease.hostname != name && lease.ip6addr != name)
|
||||
host = '%s (%s)'.format(lease.hostname, name);
|
||||
else if (lease.hostname)
|
||||
host = lease.hostname;
|
||||
else if (name)
|
||||
host = name;
|
||||
|
||||
return [
|
||||
host || '-',
|
||||
lease.ip6addrs ? lease.ip6addrs.join(' ') : lease.ip6addr,
|
||||
lease.duid,
|
||||
exp
|
||||
];
|
||||
}),
|
||||
E('em', _('There are no active leases')));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return mapEl;
|
||||
});
|
||||
}
|
||||
});
|
|
@ -1,9 +1,11 @@
|
|||
'use strict';
|
||||
'require view';
|
||||
'require dom';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require uci';
|
||||
|
||||
return L.view.extend({
|
||||
return view.extend({
|
||||
handleCommand: function(exec, args) {
|
||||
var buttons = document.querySelectorAll('.diag-action > .cbi-button');
|
||||
|
||||
|
@ -14,7 +16,7 @@ return L.view.extend({
|
|||
var out = document.querySelector('.command-output');
|
||||
out.style.display = '';
|
||||
|
||||
L.dom.content(out, [ res.stdout || '', res.stderr || '' ]);
|
||||
dom.content(out, [ res.stdout || '', res.stderr || '' ]);
|
||||
}).catch(function(err) {
|
||||
ui.addNotification(null, E('p', [ err ]))
|
||||
}).finally(function() {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
'require view';
|
||||
'require rpc';
|
||||
'require form';
|
||||
|
||||
return L.view.extend({
|
||||
return view.extend({
|
||||
callHostHints: rpc.declare({
|
||||
object: 'luci-rpc',
|
||||
method: 'getHostHints',
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
'use strict';
|
||||
'require view';
|
||||
'require dom';
|
||||
'require poll';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require uci';
|
||||
|
@ -109,7 +112,7 @@ function render_status(node, ifc, with_device) {
|
|||
function render_modal_status(node, ifc) {
|
||||
var dev = ifc ? (ifc.getDevice() || ifc.getL3Device() || ifc.getL3Device()) : null;
|
||||
|
||||
L.dom.content(node, [
|
||||
dom.content(node, [
|
||||
E('img', {
|
||||
'src': L.resource('icons/%s%s.png').format(dev ? dev.getType() : 'ethernet', (dev && dev.isUp()) ? '' : '_disabled'),
|
||||
'title': dev ? dev.getTypeI18n() : _('Not present')
|
||||
|
@ -140,7 +143,7 @@ function render_ifacebox_status(node, ifc) {
|
|||
c.push(E('small', {}, ifc.isAlias() ? _('Alias of "%s"').format(ifc.isAlias())
|
||||
: (dev ? dev.getName() : E('em', _('Not present')))));
|
||||
|
||||
L.dom.content(node, c);
|
||||
dom.content(node, c);
|
||||
|
||||
return firewall.getZoneByNetwork(ifc.getName()).then(L.bind(function(zone) {
|
||||
this.style.backgroundColor = zone ? zone.getColor() : '#EEEEEE';
|
||||
|
@ -185,7 +188,7 @@ function iface_updown(up, id, ev, force) {
|
|||
'class': 'cbi-button cbi-button-negative important',
|
||||
'click': function(ev) {
|
||||
dsc.setAttribute('disconnect', '');
|
||||
L.dom.content(dsc, E('em', _('Interface is shutting down...')));
|
||||
dom.content(dsc, E('em', _('Interface is shutting down...')));
|
||||
|
||||
ui.hideModal();
|
||||
}
|
||||
|
@ -195,13 +198,13 @@ function iface_updown(up, id, ev, force) {
|
|||
}
|
||||
else {
|
||||
dsc.setAttribute('disconnect', '');
|
||||
L.dom.content(dsc, E('em', _('Interface is shutting down...')));
|
||||
dom.content(dsc, E('em', _('Interface is shutting down...')));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
dsc.setAttribute(up ? 'reconnect' : 'disconnect', force ? 'force' : '');
|
||||
L.dom.content(dsc, E('em', up ? _('Interface is reconnecting...') : _('Interface is shutting down...')));
|
||||
dom.content(dsc, E('em', up ? _('Interface is reconnecting...') : _('Interface is shutting down...')));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,7 +227,7 @@ function get_netmask(s, use_cfgvalue) {
|
|||
return mask;
|
||||
}
|
||||
|
||||
return L.view.extend({
|
||||
return view.extend({
|
||||
poll_status: function(map, networks) {
|
||||
var resolveZone = null;
|
||||
|
||||
|
@ -245,10 +248,10 @@ return L.view.extend({
|
|||
dynamic = ifc ? ifc.isDynamic() : false;
|
||||
|
||||
if (dsc.hasAttribute('reconnect')) {
|
||||
L.dom.content(dsc, E('em', _('Interface is starting...')));
|
||||
dom.content(dsc, E('em', _('Interface is starting...')));
|
||||
}
|
||||
else if (dsc.hasAttribute('disconnect')) {
|
||||
L.dom.content(dsc, E('em', _('Interface is stopping...')));
|
||||
dom.content(dsc, E('em', _('Interface is stopping...')));
|
||||
}
|
||||
else if (ifc.getProtocol() || uci.get('network', ifc.getName()) == null) {
|
||||
render_status(dsc, ifc, false);
|
||||
|
@ -258,18 +261,18 @@ return L.view.extend({
|
|||
if (e) e.disabled = true;
|
||||
|
||||
var link = L.url('admin/system/opkg') + '?query=luci-proto';
|
||||
L.dom.content(dsc, [
|
||||
dom.content(dsc, [
|
||||
E('em', _('Unsupported protocol type.')), E('br'),
|
||||
E('a', { href: link }, _('Install protocol extensions...'))
|
||||
]);
|
||||
}
|
||||
else {
|
||||
L.dom.content(dsc, E('em', _('Interface not present or not connected yet.')));
|
||||
dom.content(dsc, E('em', _('Interface not present or not connected yet.')));
|
||||
}
|
||||
|
||||
if (stat) {
|
||||
var dev = ifc.getDevice();
|
||||
L.dom.content(stat, [
|
||||
dom.content(stat, [
|
||||
E('img', {
|
||||
'src': L.resource('icons/%s%s.png').format(dev ? dev.getType() : 'ethernet', (dev && dev.isUp()) ? '' : '_disabled'),
|
||||
'title': dev ? dev.getTypeI18n() : _('Not present')
|
||||
|
@ -336,7 +339,7 @@ return L.view.extend({
|
|||
disabled = net ? !net.isUp() : true,
|
||||
dynamic = net ? net.isDynamic() : false;
|
||||
|
||||
L.dom.content(tdEl.lastChild, [
|
||||
dom.content(tdEl.lastChild, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-neutral reconnect',
|
||||
'click': iface_updown.bind(this, true, section_id),
|
||||
|
@ -483,7 +486,7 @@ return L.view.extend({
|
|||
};
|
||||
|
||||
if (L.hasSystemFeature('firewall')) {
|
||||
o = s.taboption('firewall', widgets.ZoneSelect, '_zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>create</em> field to define a new zone and attach the interface to it.'));
|
||||
o = s.taboption('firewall', widgets.ZoneSelect, '_zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>custom</em> field to define a new zone and attach the interface to it.'));
|
||||
o.network = ifc.getName();
|
||||
o.optional = true;
|
||||
|
||||
|
@ -979,7 +982,7 @@ return L.view.extend({
|
|||
|
||||
|
||||
return m.render().then(L.bind(function(m, nodes) {
|
||||
L.Poll.add(L.bind(function() {
|
||||
poll.add(L.bind(function() {
|
||||
var section_ids = m.children[0].cfgsections(),
|
||||
tasks = [];
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
'use strict';
|
||||
'require view';
|
||||
'require form';
|
||||
'require network';
|
||||
'require tools.widgets as widgets';
|
||||
|
||||
return L.view.extend({
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return network.getDevices();
|
||||
},
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
'use strict';
|
||||
'require view';
|
||||
'require dom';
|
||||
'require poll';
|
||||
'require ui';
|
||||
'require rpc';
|
||||
'require uci';
|
||||
|
@ -67,13 +70,13 @@ function render_port_status(node, portstate) {
|
|||
return null;
|
||||
|
||||
if (!portstate || !portstate.link)
|
||||
L.dom.content(node, [
|
||||
dom.content(node, [
|
||||
E('img', { src: L.resource('icons/port_down.png') }),
|
||||
E('br'),
|
||||
_('no link')
|
||||
]);
|
||||
else
|
||||
L.dom.content(node, [
|
||||
dom.content(node, [
|
||||
E('img', { src: L.resource('icons/port_up.png') }),
|
||||
E('br'),
|
||||
'%d'.format(portstate.speed) + _('baseT'),
|
||||
|
@ -112,7 +115,7 @@ var callSwconfigPortState = rpc.declare({
|
|||
expect: { result: [] }
|
||||
});
|
||||
|
||||
return L.view.extend({
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return network.getSwitchTopologies().then(function(topologies) {
|
||||
var tasks = [];
|
||||
|
@ -365,7 +368,7 @@ return L.view.extend({
|
|||
});
|
||||
}
|
||||
|
||||
L.Poll.add(L.bind(update_port_status, m, topologies));
|
||||
poll.add(L.bind(update_port_status, m, topologies));
|
||||
|
||||
return m.render();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
'use strict';
|
||||
'require view';
|
||||
'require dom';
|
||||
'require poll';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require rpc';
|
||||
|
@ -29,7 +32,7 @@ function render_radio_badge(radioDev) {
|
|||
]);
|
||||
}
|
||||
|
||||
function render_signal_badge(signalPercent, signalValue, noiseValue, wrap) {
|
||||
function render_signal_badge(signalPercent, signalValue, noiseValue, wrap, mode) {
|
||||
var icon, title, value;
|
||||
|
||||
if (signalPercent < 0)
|
||||
|
@ -45,20 +48,42 @@ function render_signal_badge(signalPercent, signalValue, noiseValue, wrap) {
|
|||
else
|
||||
icon = L.resource('icons/signal-75-100.png');
|
||||
|
||||
if (signalValue != null && signalValue != 0 && noiseValue != null && noiseValue != 0) {
|
||||
value = '%d/%d\xa0%s'.format(signalValue, noiseValue, _('dBm'));
|
||||
title = '%s: %d %s / %s: %d %s / %s %d'.format(
|
||||
_('Signal'), signalValue, _('dBm'),
|
||||
_('Noise'), noiseValue, _('dBm'),
|
||||
_('SNR'), signalValue - noiseValue);
|
||||
}
|
||||
else if (signalValue != null && signalValue != 0) {
|
||||
value = '%d %s'.format(signalValue, _('dBm'));
|
||||
title = '%s: %d %s'.format(_('Signal'), signalValue, _('dBm'));
|
||||
if (signalValue != null && signalValue != 0) {
|
||||
if (noiseValue != null && noiseValue != 0) {
|
||||
value = '%d/%d\xa0%s'.format(signalValue, noiseValue, _('dBm'));
|
||||
title = '%s: %d %s / %s: %d %s / %s %d'.format(
|
||||
_('Signal'), signalValue, _('dBm'),
|
||||
_('Noise'), noiseValue, _('dBm'),
|
||||
_('SNR'), signalValue - noiseValue);
|
||||
}
|
||||
else {
|
||||
value = '%d\xa0%s'.format(signalValue, _('dBm'));
|
||||
title = '%s: %d %s'.format(_('Signal'), signalValue, _('dBm'));
|
||||
}
|
||||
}
|
||||
else if (signalPercent > -1) {
|
||||
value = '\xa0---\xa0';
|
||||
title = _('No signal');
|
||||
switch (mode) {
|
||||
case 'ap':
|
||||
title = _('No client associated');
|
||||
break;
|
||||
|
||||
case 'sta':
|
||||
case 'adhoc':
|
||||
case 'mesh':
|
||||
title = _('Not associated');
|
||||
break;
|
||||
|
||||
default:
|
||||
title = _('No RX signal');
|
||||
}
|
||||
|
||||
if (noiseValue != null && noiseValue != 0) {
|
||||
value = '---/%d\x0a%s'.format(noiseValue, _('dBm'));
|
||||
title = '%s / %s: %d %s'.format(title, _('Noise'), noiseValue, _('dBm'));
|
||||
}
|
||||
else {
|
||||
value = '---\xa0%s'.format(_('dBm'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = E('em', {}, E('small', {}, [ _('disabled') ]));
|
||||
|
@ -80,7 +105,9 @@ function render_signal_badge(signalPercent, signalValue, noiseValue, wrap) {
|
|||
}
|
||||
|
||||
function render_network_badge(radioNet) {
|
||||
return render_signal_badge(radioNet.isUp() ? radioNet.getSignalPercent() : -1, radioNet.getSignal(), radioNet.getNoise());
|
||||
return render_signal_badge(
|
||||
radioNet.isUp() ? radioNet.getSignalPercent() : -1,
|
||||
radioNet.getSignal(), radioNet.getNoise(), false, radioNet.getMode());
|
||||
}
|
||||
|
||||
function render_radio_status(radioDev, wifiNets) {
|
||||
|
@ -143,7 +170,9 @@ function render_modal_status(node, radioNet) {
|
|||
if (node == null)
|
||||
node = E('span', { 'class': 'ifacebadge large', 'data-network': radioNet.getName() }, [ E('small'), E('span') ]);
|
||||
|
||||
L.dom.content(node.firstElementChild, render_signal_badge(disabled ? -1 : radioNet.getSignalPercent(), radioNet.getSignal(), noise, true));
|
||||
dom.content(node.firstElementChild, render_signal_badge(
|
||||
disabled ? -1 : radioNet.getSignalPercent(),
|
||||
radioNet.getSignal(), noise, true, radioNet.getMode()));
|
||||
|
||||
L.itemlist(node.lastElementChild, [
|
||||
_('Mode'), mode,
|
||||
|
@ -159,7 +188,7 @@ function render_modal_status(node, radioNet) {
|
|||
], [ ' | ', E('br'), E('br'), E('br'), E('br'), E('br'), ' | ', E('br'), ' | ' ]);
|
||||
|
||||
if (!is_assoc)
|
||||
L.dom.append(node.lastElementChild, E('em', disabled ? _('Wireless is disabled') : _('Wireless is not associated')));
|
||||
dom.append(node.lastElementChild, E('em', disabled ? _('Wireless is disabled') : _('Wireless is not associated')));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -190,7 +219,7 @@ function radio_restart(id, ev) {
|
|||
btn.disabled = true;
|
||||
|
||||
dsc.setAttribute('restart', '');
|
||||
L.dom.content(dsc, E('em', _('Device is restarting…')));
|
||||
dom.content(dsc, E('em', _('Device is restarting…')));
|
||||
}
|
||||
|
||||
function network_updown(id, map, ev) {
|
||||
|
@ -233,6 +262,31 @@ function next_free_sid(offset) {
|
|||
return sid;
|
||||
}
|
||||
|
||||
function add_dependency_permutations(o, deps) {
|
||||
var res = null;
|
||||
|
||||
for (var key in deps) {
|
||||
if (!deps.hasOwnProperty(key) || !Array.isArray(deps[key]))
|
||||
continue;
|
||||
|
||||
var list = deps[key],
|
||||
tmp = [];
|
||||
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
for (var k = 0; k < (res ? res.length : 1); k++) {
|
||||
var item = (res ? Object.assign({}, res[k]) : {});
|
||||
item[key] = list[j];
|
||||
tmp.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
res = tmp;
|
||||
}
|
||||
|
||||
for (var i = 0; i < (res ? res.length : 0); i++)
|
||||
o.depends(res[i]);
|
||||
}
|
||||
|
||||
var CBIWifiFrequencyValue = form.Value.extend({
|
||||
callFrequencyList: rpc.declare({
|
||||
object: 'iwinfo',
|
||||
|
@ -381,7 +435,7 @@ var CBIWifiFrequencyValue = form.Value.extend({
|
|||
renderWidget: function(section_id, option_index, cfgvalue) {
|
||||
var elem = E('div');
|
||||
|
||||
L.dom.content(elem, [
|
||||
dom.content(elem, [
|
||||
E('label', { 'style': 'float:left; margin-right:3px' }, [
|
||||
_('Mode'), E('br'),
|
||||
E('select', {
|
||||
|
@ -469,7 +523,7 @@ var CBIWifiTxPowerValue = form.ListValue.extend({
|
|||
var widget = form.ListValue.prototype.renderWidget.apply(this, [section_id, option_index, cfgvalue]);
|
||||
widget.firstElementChild.style.width = 'auto';
|
||||
|
||||
L.dom.append(widget, E('span', [
|
||||
dom.append(widget, E('span', [
|
||||
' - ', _('Current power'), ': ',
|
||||
E('span', [ this.powerval != null ? '%d dBm'.format(this.powerval) : E('em', _('unknown')) ]),
|
||||
this.poweroff ? ' + %d dB offset = %s dBm'.format(this.poweroff, this.powerval != null ? this.powerval + this.poweroff : '?') : ''
|
||||
|
@ -513,7 +567,7 @@ var CBIWifiCountryValue = form.Value.extend({
|
|||
}
|
||||
});
|
||||
|
||||
return L.view.extend({
|
||||
return view.extend({
|
||||
poll_status: function(map, data) {
|
||||
var rows = map.querySelectorAll('.cbi-section-table-row[data-sid]');
|
||||
|
||||
|
@ -527,16 +581,16 @@ return L.view.extend({
|
|||
busy = btns[0].classList.contains('spinning') || btns[1].classList.contains('spinning') || btns[2].classList.contains('spinning');
|
||||
|
||||
if (radioDev) {
|
||||
L.dom.content(badge, render_radio_badge(radioDev));
|
||||
L.dom.content(stat, render_radio_status(radioDev, data[2].filter(function(n) { return n.getWifiDeviceName() == radioDev.getName() })));
|
||||
dom.content(badge, render_radio_badge(radioDev));
|
||||
dom.content(stat, render_radio_status(radioDev, data[2].filter(function(n) { return n.getWifiDeviceName() == radioDev.getName() })));
|
||||
}
|
||||
else {
|
||||
L.dom.content(badge, render_network_badge(radioNet));
|
||||
L.dom.content(stat, render_network_status(radioNet));
|
||||
dom.content(badge, render_network_badge(radioNet));
|
||||
dom.content(stat, render_network_status(radioNet));
|
||||
}
|
||||
|
||||
if (stat.hasAttribute('restart'))
|
||||
L.dom.content(stat, E('em', _('Device is restarting…')));
|
||||
dom.content(stat, E('em', _('Device is restarting…')));
|
||||
|
||||
btns[0].disabled = busy;
|
||||
btns[1].disabled = busy;
|
||||
|
@ -594,7 +648,7 @@ return L.view.extend({
|
|||
row.push(E('button', {
|
||||
'class': 'cbi-button cbi-button-remove',
|
||||
'click': L.bind(function(net, mac, ev) {
|
||||
L.dom.parent(ev.currentTarget, '.tr').style.opacity = 0.5;
|
||||
dom.parent(ev.currentTarget, '.tr').style.opacity = 0.5;
|
||||
ev.currentTarget.classList.add('spinning');
|
||||
ev.currentTarget.disabled = true;
|
||||
ev.currentTarget.blur();
|
||||
|
@ -895,7 +949,7 @@ return L.view.extend({
|
|||
o = ss.taboption('general', form.Value, 'bssid', _('<abbr title="Basic Service Set Identifier">BSSID</abbr>'));
|
||||
o.datatype = 'macaddr';
|
||||
|
||||
o = ss.taboption('general', widgets.NetworkSelect, 'network', _('Network'), _('Choose the network(s) you want to attach to this wireless interface or fill out the <em>create</em> field to define a new network.'));
|
||||
o = ss.taboption('general', widgets.NetworkSelect, 'network', _('Network'), _('Choose the network(s) you want to attach to this wireless interface or fill out the <em>custom</em> field to define a new network.'));
|
||||
o.rmempty = true;
|
||||
o.multiple = true;
|
||||
o.novirtual = true;
|
||||
|
@ -1075,7 +1129,7 @@ return L.view.extend({
|
|||
var e = this.section.children.filter(function(o) { return o.option == 'encryption' })[0].formvalue(section_id),
|
||||
co = this.section.children.filter(function(o) { return o.option == 'cipher' })[0], c = co.formvalue(section_id);
|
||||
|
||||
if (value == 'wpa' || value == 'wpa2')
|
||||
if (value == 'wpa' || value == 'wpa2' || value == 'wpa3' || value == 'wpa3-mixed')
|
||||
uci.unset('wireless', section_id, 'key');
|
||||
|
||||
if (co.isActive(section_id) && e && (c == 'tkip' || c == 'ccmp' || c == 'tkip+ccmp'))
|
||||
|
@ -1087,6 +1141,8 @@ return L.view.extend({
|
|||
o = ss.taboption('encryption', form.ListValue, 'cipher', _('Cipher'));
|
||||
o.depends('encryption', 'wpa');
|
||||
o.depends('encryption', 'wpa2');
|
||||
o.depends('encryption', 'wpa3');
|
||||
o.depends('encryption', 'wpa3-mixed');
|
||||
o.depends('encryption', 'psk');
|
||||
o.depends('encryption', 'psk2');
|
||||
o.depends('encryption', 'wpa-mixed');
|
||||
|
@ -1128,9 +1184,13 @@ return L.view.extend({
|
|||
var has_ap_owe = L.hasSystemFeature('hostapd', 'owe'),
|
||||
has_sta_owe = L.hasSystemFeature('wpasupplicant', 'owe');
|
||||
|
||||
// Probe Suite-B support
|
||||
var has_ap_eap192 = L.hasSystemFeature('hostapd', 'suiteb192'),
|
||||
has_sta_eap192 = L.hasSystemFeature('wpasupplicant', 'suiteb192');
|
||||
|
||||
|
||||
if (has_hostapd || has_supplicant) {
|
||||
crypto_modes.push(['psk2', 'WPA2-PSK', 33]);
|
||||
crypto_modes.push(['psk2', 'WPA2-PSK', 35]);
|
||||
crypto_modes.push(['psk-mixed', 'WPA-PSK/WPA2-PSK Mixed Mode', 22]);
|
||||
crypto_modes.push(['psk', 'WPA-PSK', 21]);
|
||||
}
|
||||
|
@ -1144,7 +1204,12 @@ return L.view.extend({
|
|||
}
|
||||
|
||||
if (has_ap_eap || has_sta_eap) {
|
||||
crypto_modes.push(['wpa2', 'WPA2-EAP', 32]);
|
||||
if (has_ap_eap192 || has_sta_eap192) {
|
||||
crypto_modes.push(['wpa3', 'WPA3-EAP', 33]);
|
||||
crypto_modes.push(['wpa3-mixed', 'WPA2-EAP/WPA3-EAP Mixed Mode', 32]);
|
||||
}
|
||||
|
||||
crypto_modes.push(['wpa2', 'WPA2-EAP', 34]);
|
||||
crypto_modes.push(['wpa', 'WPA-EAP', 20]);
|
||||
}
|
||||
|
||||
|
@ -1163,6 +1228,8 @@ return L.view.extend({
|
|||
'sae-mixed': has_ap_sae || _('Requires hostapd with SAE support'),
|
||||
'wpa': has_ap_eap || _('Requires hostapd with EAP support'),
|
||||
'wpa2': has_ap_eap || _('Requires hostapd with EAP support'),
|
||||
'wpa3': has_ap_eap192 || _('Requires hostapd with EAP Suite-B support'),
|
||||
'wpa3-mixed': has_ap_eap192 || _('Requires hostapd with EAP Suite-B support'),
|
||||
'owe': has_ap_owe || _('Requires hostapd with OWE support')
|
||||
},
|
||||
'sta': {
|
||||
|
@ -1175,6 +1242,8 @@ return L.view.extend({
|
|||
'sae-mixed': has_sta_sae || _('Requires wpa-supplicant with SAE support'),
|
||||
'wpa': has_sta_eap || _('Requires wpa-supplicant with EAP support'),
|
||||
'wpa2': has_sta_eap || _('Requires wpa-supplicant with EAP support'),
|
||||
'wpa3': has_sta_eap192 || _('Requires wpa-supplicant with EAP Suite-B support'),
|
||||
'wpa3-mixed': has_sta_eap192 || _('Requires wpa-supplicant with EAP Suite-B support'),
|
||||
'owe': has_sta_owe || _('Requires wpa-supplicant with OWE support')
|
||||
},
|
||||
'adhoc': {
|
||||
|
@ -1237,74 +1306,47 @@ return L.view.extend({
|
|||
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'auth_server', _('Radius-Authentication-Server'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.datatype = 'host(0)';
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'auth_port', _('Radius-Authentication-Port'), _('Default %d').format(1812));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.datatype = 'port';
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'auth_secret', _('Radius-Authentication-Secret'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.password = true;
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'acct_server', _('Radius-Accounting-Server'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.datatype = 'host(0)';
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'acct_port', _('Radius-Accounting-Port'), _('Default %d').format(1813));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.datatype = 'port';
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'acct_secret', _('Radius-Accounting-Secret'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.password = true;
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'dae_client', _('DAE-Client'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.datatype = 'host(0)';
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'dae_port', _('DAE-Port'), _('Default %d').format(3799));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.datatype = 'port';
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'dae_secret', _('DAE-Secret'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.rmempty = true;
|
||||
o.password = true;
|
||||
|
||||
|
@ -1372,29 +1414,13 @@ return L.view.extend({
|
|||
var has_80211r = L.hasSystemFeature('hostapd', '11r') || L.hasSystemFeature('hostapd', 'eap');
|
||||
|
||||
o = ss.taboption('encryption', form.Flag, 'ieee80211r', _('802.11r Fast Transition'), _('Enables fast roaming among access points that belong to the same Mobility Domain'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
if (has_80211r) {
|
||||
o.depends({ mode: 'ap', encryption: 'psk' });
|
||||
o.depends({ mode: 'ap', encryption: 'psk2' });
|
||||
o.depends({ mode: 'ap', encryption: 'psk-mixed' });
|
||||
o.depends({ mode: 'ap', encryption: 'sae' });
|
||||
o.depends({ mode: 'ap', encryption: 'sae-mixed' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'psk' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'psk2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'psk-mixed' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'sae' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'sae-mixed' });
|
||||
}
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
if (has_80211r)
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['psk', 'psk2', 'psk-mixed', 'sae', 'sae-mixed'] });
|
||||
o.rmempty = true;
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'nasid', _('NAS ID'), _('Used for two different purposes: RADIUS NAS ID and 802.11r R0KH-ID. Not needed with normal WPA(2)-PSK.'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.depends({ ieee80211r: '1' });
|
||||
o.rmempty = true;
|
||||
|
||||
|
@ -1452,19 +1478,13 @@ return L.view.extend({
|
|||
o.value('ttls', 'TTLS');
|
||||
o.value('peap', 'PEAP');
|
||||
o.value('fast', 'FAST');
|
||||
o.depends({ mode: 'sta', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
|
||||
o = ss.taboption('encryption', form.Flag, 'ca_cert_usesystem', _('Use system certificates'), _("Validate server certificate using built-in system CA bundle,<br />requires the \"ca-bundle\" package"));
|
||||
o.enabled = '1';
|
||||
o.disabled = '0';
|
||||
o.default = o.disabled;
|
||||
o.depends({ mode: 'sta', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
o.validate = function(section_id, value) {
|
||||
if (value == '1' && !L.hasSystemFeature('cabundle')) {
|
||||
return _("This option cannot be used because the ca-bundle package is not installed.");
|
||||
|
@ -1473,52 +1493,28 @@ return L.view.extend({
|
|||
};
|
||||
|
||||
o = ss.taboption('encryption', form.FileUpload, 'ca_cert', _('Path to CA-Certificate'));
|
||||
o.depends({ mode: 'sta', encryption: 'wpa', ca_cert_usesystem: '0' });
|
||||
o.depends({ mode: 'sta', encryption: 'wpa2', ca_cert_usesystem: '0' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa', ca_cert_usesystem: '0' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa2', ca_cert_usesystem: '0' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], ca_cert_usesystem: ['0'] });
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'subject_match', _('Certificate constraint (Subject)'), _("Certificate constraint substring - e.g. /CN=wifi.mycompany.com<br />See `logread -f` during handshake for actual values"));
|
||||
o.depends({ mode: 'sta', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
|
||||
o = ss.taboption('encryption', form.DynamicList, 'altsubject_match', _('Certificate constraint (SAN)'), _("Certificate constraint(s) via Subject Alternate Name values<br />(supported attributes: EMAIL, DNS, URI) - e.g. DNS:wifi.mycompany.com"));
|
||||
o.depends({ mode: 'sta', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
|
||||
o = ss.taboption('encryption', form.DynamicList, 'domain_match', _('Certificate constraint (Domain)'), _("Certificate constraint(s) against DNS SAN values (if available)<br />or Subject CN (exact match)"));
|
||||
o.depends({ mode: 'sta', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
|
||||
o = ss.taboption('encryption', form.DynamicList, 'domain_suffix_match', _('Certificate constraint (Wildcard)'), _("Certificate constraint(s) against DNS SAN values (if available)<br />or Subject CN (suffix match)"));
|
||||
o.depends({ mode: 'sta', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
|
||||
o = ss.taboption('encryption', form.FileUpload, 'client_cert', _('Path to Client-Certificate'));
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['tls'] });
|
||||
|
||||
o = ss.taboption('encryption', form.FileUpload, 'priv_key', _('Path to Private Key'));
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['tls'] });
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'priv_key_pwd', _('Password of Private Key'));
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['tls'] });
|
||||
o.password = true;
|
||||
|
||||
o = ss.taboption('encryption', form.ListValue, 'auth', _('Authentication'));
|
||||
|
@ -1526,22 +1522,11 @@ return L.view.extend({
|
|||
o.value('CHAP', 'CHAP');
|
||||
o.value('MSCHAP', 'MSCHAP');
|
||||
o.value('MSCHAPV2', 'MSCHAPv2');
|
||||
o.value('EAP-GTC');
|
||||
o.value('EAP-MD5');
|
||||
o.value('EAP-MSCHAPV2');
|
||||
o.value('EAP-TLS');
|
||||
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa' });
|
||||
o.value('EAP-GTC', 'EAP-GTC');
|
||||
o.value('EAP-MD5', 'EAP-MD5');
|
||||
o.value('EAP-MSCHAPV2', 'EAP-MSCHAPv2');
|
||||
o.value('EAP-TLS', 'EAP-TLS');
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['fast', 'peap', 'ttls'] });
|
||||
|
||||
o.validate = function(section_id, value) {
|
||||
var eo = this.section.children.filter(function(o) { return o.option == 'eap_type' })[0],
|
||||
|
@ -1557,10 +1542,7 @@ return L.view.extend({
|
|||
o.enabled = '1';
|
||||
o.disabled = '0';
|
||||
o.default = o.disabled;
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
|
||||
o.validate = function(section_id, value) {
|
||||
if (value == '1' && !L.hasSystemFeature('cabundle')) {
|
||||
return _("This option cannot be used because the ca-bundle package is not installed.");
|
||||
|
@ -1569,103 +1551,38 @@ return L.view.extend({
|
|||
};
|
||||
|
||||
o = ss.taboption('encryption', form.FileUpload, 'ca_cert2', _('Path to inner CA-Certificate'));
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa', ca_cert2_usesystem: '0' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2', ca_cert2_usesystem: '0' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa', ca_cert2_usesystem: '0' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2', ca_cert2_usesystem: '0' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'], ca_cert2_usesystem: ['0'] });
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'subject_match2', _('Inner certificate constraint (Subject)'), _("Certificate constraint substring - e.g. /CN=wifi.mycompany.com<br />See `logread -f` during handshake for actual values"));
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
|
||||
|
||||
o = ss.taboption('encryption', form.DynamicList, 'altsubject_match2', _('Inner certificate constraint (SAN)'), _("Certificate constraint(s) via Subject Alternate Name values<br />(supported attributes: EMAIL, DNS, URI) - e.g. DNS:wifi.mycompany.com"));
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
|
||||
|
||||
o = ss.taboption('encryption', form.DynamicList, 'domain_match2', _('Inner certificate constraint (Domain)'), _("Certificate constraint(s) against DNS SAN values (if available)<br />or Subject CN (exact match)"));
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
|
||||
|
||||
o = ss.taboption('encryption', form.DynamicList, 'domain_suffix_match2', _('Inner certificate constraint (Wildcard)'), _("Certificate constraint(s) against DNS SAN values (if available)<br />or Subject CN (suffix match)"));
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
|
||||
|
||||
o = ss.taboption('encryption', form.FileUpload, 'client_cert2', _('Path to inner Client-Certificate'));
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
|
||||
|
||||
o = ss.taboption('encryption', form.FileUpload, 'priv_key2', _('Path to inner Private Key'));
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'priv_key2_pwd', _('Password of inner Private Key'));
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', auth: 'EAP-TLS', encryption: 'wpa2' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], auth: ['EAP-TLS'] });
|
||||
o.password = true;
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'identity', _('Identity'));
|
||||
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['fast', 'peap', 'tls', 'ttls'] });
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'anonymous_identity', _('Anonymous Identity'));
|
||||
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'tls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'tls', encryption: 'wpa' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['fast', 'peap', 'tls', 'ttls'] });
|
||||
|
||||
o = ss.taboption('encryption', form.Value, 'password', _('Password'));
|
||||
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'fast', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'peap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', eap_type: 'ttls', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'fast', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'peap', encryption: 'wpa' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', eap_type: 'ttls', encryption: 'wpa' });
|
||||
add_dependency_permutations(o, { mode: ['sta', 'sta-wds'], encryption: ['wpa', 'wpa2', 'wpa3', 'wpa3-mixed'], eap_type: ['fast', 'peap', 'ttls'] });
|
||||
o.password = true;
|
||||
|
||||
|
||||
|
@ -1676,32 +1593,10 @@ return L.view.extend({
|
|||
o.value('', _('Disabled'));
|
||||
o.value('1', _('Optional'));
|
||||
o.value('2', _('Required'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap', encryption: 'psk2' });
|
||||
o.depends({ mode: 'ap', encryption: 'psk-mixed' });
|
||||
o.depends({ mode: 'ap', encryption: 'sae' });
|
||||
o.depends({ mode: 'ap', encryption: 'sae-mixed' });
|
||||
o.depends({ mode: 'ap', encryption: 'owe' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'psk2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'psk-mixed' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'sae' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'sae-mixed' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'owe' });
|
||||
o.depends({ mode: 'sta', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'sta', encryption: 'psk2' });
|
||||
o.depends({ mode: 'sta', encryption: 'psk-mixed' });
|
||||
o.depends({ mode: 'sta', encryption: 'sae' });
|
||||
o.depends({ mode: 'sta', encryption: 'sae-mixed' });
|
||||
o.depends({ mode: 'sta', encryption: 'owe' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'psk2' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'psk-mixed' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'sae' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'sae-mixed' });
|
||||
o.depends({ mode: 'sta-wds', encryption: 'owe' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds', 'sta', 'sta-wds'], encryption: ['owe', 'psk2', 'psk-mixed', 'sae', 'sae-mixed', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
|
||||
o.defaults = {
|
||||
'2': [{ encryption: 'sae' }, { encryption: 'owe' }],
|
||||
'2': [{ encryption: 'sae' }, { encryption: 'owe' }, { encryption: 'wpa3' }, { encryption: 'wpa3-mixed' }],
|
||||
'1': [{ encryption: 'sae-mixed'}],
|
||||
'': []
|
||||
};
|
||||
|
@ -1722,16 +1617,7 @@ return L.view.extend({
|
|||
};
|
||||
|
||||
o = ss.taboption('encryption', form.Flag, 'wpa_disable_eapol_key_retries', _('Enable key reinstallation (KRACK) countermeasures'), _('Complicates key reinstallation attacks on the client side by disabling retransmission of EAPOL-Key frames that are used to install keys. This workaround might cause interoperability issues and reduced robustness of key negotiation especially in environments with heavy traffic load.'));
|
||||
o.depends({ mode: 'ap', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap', encryption: 'psk2' });
|
||||
o.depends({ mode: 'ap', encryption: 'psk-mixed' });
|
||||
o.depends({ mode: 'ap', encryption: 'sae' });
|
||||
o.depends({ mode: 'ap', encryption: 'sae-mixed' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'wpa2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'psk2' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'psk-mixed' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'sae' });
|
||||
o.depends({ mode: 'ap-wds', encryption: 'sae-mixed' });
|
||||
add_dependency_permutations(o, { mode: ['ap', 'ap-wds'], encryption: ['psk2', 'psk-mixed', 'sae', 'sae-mixed', 'wpa2', 'wpa3', 'wpa3-mixed'] });
|
||||
|
||||
if (L.hasSystemFeature('hostapd', 'cli') && L.hasSystemFeature('wpasupplicant')) {
|
||||
o = ss.taboption('encryption', form.Flag, 'wps_pushbutton', _('Enable WPS pushbutton, requires WPA(2)-PSK/WPA3-SAE'))
|
||||
|
@ -1793,8 +1679,8 @@ return L.view.extend({
|
|||
|
||||
this.pollFn = L.bind(this.handleScanRefresh, this, radioDev, {}, table, stop);
|
||||
|
||||
L.Poll.add(this.pollFn);
|
||||
L.Poll.start();
|
||||
poll.add(this.pollFn);
|
||||
poll.start();
|
||||
};
|
||||
|
||||
s.handleScanRefresh = function(radioDev, scanCache, table, stop) {
|
||||
|
@ -1860,12 +1746,12 @@ return L.view.extend({
|
|||
var btn = ev.currentTarget;
|
||||
|
||||
if (btn.getAttribute('data-state') == 'stop') {
|
||||
L.Poll.remove(this.pollFn);
|
||||
poll.remove(this.pollFn);
|
||||
btn.firstChild.data = _('Start refresh');
|
||||
btn.setAttribute('data-state', 'start');
|
||||
}
|
||||
else {
|
||||
L.Poll.add(this.pollFn);
|
||||
poll.add(this.pollFn);
|
||||
btn.firstChild.data = _('Stop refresh');
|
||||
btn.setAttribute('data-state', 'stop');
|
||||
btn.classList.add('spinning');
|
||||
|
@ -1874,14 +1760,14 @@ return L.view.extend({
|
|||
};
|
||||
|
||||
s.handleScanAbort = function(ev) {
|
||||
var md = L.dom.parent(ev.target, 'div[aria-modal="true"]');
|
||||
var md = dom.parent(ev.target, 'div[aria-modal="true"]');
|
||||
if (md) {
|
||||
md.style.maxWidth = '';
|
||||
md.style.maxHeight = '';
|
||||
}
|
||||
|
||||
ui.hideModal();
|
||||
L.Poll.remove(this.pollFn);
|
||||
poll.remove(this.pollFn);
|
||||
|
||||
this.pollFn = null;
|
||||
};
|
||||
|
@ -2038,7 +1924,7 @@ return L.view.extend({
|
|||
bssid.default = '0';
|
||||
}
|
||||
|
||||
zone = s2.option(widgets.ZoneSelect, 'zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>create</em> field to define a new zone and attach the interface to it.'));
|
||||
zone = s2.option(widgets.ZoneSelect, 'zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>custom</em> field to define a new zone and attach the interface to it.'));
|
||||
zone.default = 'wan';
|
||||
|
||||
return m2.render().then(L.bind(function(nodes) {
|
||||
|
@ -2101,7 +1987,7 @@ return L.view.extend({
|
|||
};
|
||||
|
||||
return m.render().then(L.bind(function(m, nodes) {
|
||||
L.Poll.add(L.bind(function() {
|
||||
poll.add(L.bind(function() {
|
||||
var section_ids = m.children[0].cfgsections(),
|
||||
tasks = [ network.getHostHints(), network.getWifiDevices() ];
|
||||
|
||||
|
|
Loading…
Reference in a new issue