luci-proto-wireguard: handle multiple peers in imported configuration
When importing a fully configuration, import all peer entries from it
instead of non-deterministically merging all peer keys into one.
When importing a remote configuration as peer, only use the setting from
the peer section matching our local interface pubkey.
Also relabel the `Import peer configuration` button to
`Import configuration as peer` in order to be more explicit.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit 94bfa33452
)
This commit is contained in:
parent
d09fbe0bbf
commit
18e6040bb8
1 changed files with 68 additions and 46 deletions
|
@ -253,20 +253,26 @@ return network.registerProtocol('wireguard', {
|
|||
ss.parseConfig = function(data) {
|
||||
var lines = String(data).split(/(\r?\n)+/),
|
||||
section = null,
|
||||
config = {};
|
||||
config = { peers: [] },
|
||||
s;
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i].replace(/#.*$/, '').trim();
|
||||
|
||||
if (line.match(/^\[(\w+)\]$/)) {
|
||||
section = RegExp.$1.toLowerCase();
|
||||
|
||||
if (section == 'peer')
|
||||
config.peers.push(s = {});
|
||||
else
|
||||
s = config;
|
||||
}
|
||||
else if (section && line.match(/^(\w+)\s*=\s*(.+)$/)) {
|
||||
var key = RegExp.$1,
|
||||
val = RegExp.$2.trim();
|
||||
|
||||
if (val.length)
|
||||
config[section + '_' + key.toLowerCase()] = val;
|
||||
s[section + '_' + key.toLowerCase()] = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,37 +298,41 @@ return network.registerProtocol('wireguard', {
|
|||
if (!stubValidator.apply('port', config.interface_listenport || '0'))
|
||||
return _('ListenPort setting is invalid');
|
||||
|
||||
if (config.peer_publickey != null && validateBase64(null, config.peer_publickey) !== true)
|
||||
return _('PublicKey setting is invalid');
|
||||
for (var i = 0; i < config.peers.length; i++) {
|
||||
var pconf = config.peers[i];
|
||||
|
||||
if (config.peer_presharedkey != null && validateBase64(null, config.peer_presharedkey) !== true)
|
||||
return _('PresharedKey setting is invalid');
|
||||
if (pconf.peer_publickey != null && validateBase64(null, pconf.peer_publickey) !== true)
|
||||
return _('PublicKey setting is invalid');
|
||||
|
||||
if (config.peer_allowedips) {
|
||||
config.peer_allowedips = config.peer_allowedips.split(/[, ]+/);
|
||||
if (pconf.peer_presharedkey != null && validateBase64(null, pconf.peer_presharedkey) !== true)
|
||||
return _('PresharedKey setting is invalid');
|
||||
|
||||
for (var i = 0; i < config.peer_allowedips.length; i++)
|
||||
if (!stubValidator.apply('ipaddr', config.peer_allowedips[i]))
|
||||
return _('AllowedIPs setting is invalid');
|
||||
if (pconf.peer_allowedips) {
|
||||
pconf.peer_allowedips = pconf.peer_allowedips.split(/[, ]+/);
|
||||
|
||||
for (var j = 0; j < pconf.peer_allowedips.length; j++)
|
||||
if (!stubValidator.apply('ipaddr', pconf.peer_allowedips[j]))
|
||||
return _('AllowedIPs setting is invalid');
|
||||
}
|
||||
else {
|
||||
pconf.peer_allowedips = [ '0.0.0.0/0', '::/0' ];
|
||||
}
|
||||
|
||||
if (pconf.peer_endpoint) {
|
||||
var host_port = pconf.peer_endpoint.match(/^\[([a-fA-F0-9:]+)\]:(\d+)$/) || pconf.peer_endpoint.match(/^(.+):(\d+)$/);
|
||||
|
||||
if (!host_port || !stubValidator.apply('host', host_port[1]) || !stubValidator.apply('port', host_port[2]))
|
||||
return _('Endpoint setting is invalid');
|
||||
|
||||
pconf.peer_endpoint = [ host_port[1], host_port[2] ];
|
||||
}
|
||||
|
||||
if (pconf.peer_persistentkeepalive == 'off' || pconf.peer_persistentkeepalive == '0')
|
||||
delete pconf.peer_persistentkeepalive;
|
||||
|
||||
if (!stubValidator.apply('port', pconf.peer_persistentkeepalive || '0'))
|
||||
return _('PersistentKeepAlive setting is invalid');
|
||||
}
|
||||
else {
|
||||
config.peer_allowedips = [ '0.0.0.0/0', '::/0' ];
|
||||
}
|
||||
|
||||
if (config.peer_endpoint) {
|
||||
var host_port = config.peer_endpoint.match(/^\[([a-fA-F0-9:]+)\]:(\d+)$/) || config.peer_endpoint.match(/^(.+):(\d+)$/);
|
||||
|
||||
if (!host_port || !stubValidator.apply('host', host_port[1]) || !stubValidator.apply('port', host_port[2]))
|
||||
return _('Endpoint setting is invalid');
|
||||
|
||||
config.peer_endpoint = [ host_port[1], host_port[2] ];
|
||||
}
|
||||
|
||||
if (config.peer_persistentkeepalive == 'off' || config.peer_persistentkeepalive == '0')
|
||||
delete config.peer_persistentkeepalive;
|
||||
|
||||
if (!stubValidator.apply('port', config.peer_persistentkeepalive || '0'))
|
||||
return _('PersistentKeepAlive setting is invalid');
|
||||
|
||||
return config;
|
||||
};
|
||||
|
@ -356,22 +366,25 @@ return network.registerProtocol('wireguard', {
|
|||
s.getOption('dns').getUIElement(s.section).setValue(config.interface_dns);
|
||||
}
|
||||
|
||||
var sid = uci.add('network', 'wireguard_' + s.section);
|
||||
for (var i = 0; i < config.peers.length; i++) {
|
||||
var pconf = config.peers[i];
|
||||
var sid = uci.add('network', 'wireguard_' + s.section);
|
||||
|
||||
uci.sections('network', 'wireguard_' + s.section, function(peer) {
|
||||
if (peer.public_key == config.peer_publickey)
|
||||
uci.remove('network', peer['.name']);
|
||||
});
|
||||
uci.sections('network', 'wireguard_' + s.section, function(peer) {
|
||||
if (peer.public_key == pconf.peer_publickey)
|
||||
uci.remove('network', peer['.name']);
|
||||
});
|
||||
|
||||
uci.set('network', sid, 'description', comment || _('Imported peer configuration'));
|
||||
uci.set('network', sid, 'public_key', config.peer_publickey);
|
||||
uci.set('network', sid, 'preshared_key', config.peer_presharedkey);
|
||||
uci.set('network', sid, 'allowed_ips', config.peer_allowedips);
|
||||
uci.set('network', sid, 'persistent_keepalive', config.peer_persistentkeepalive);
|
||||
uci.set('network', sid, 'description', comment || _('Imported peer configuration'));
|
||||
uci.set('network', sid, 'public_key', pconf.peer_publickey);
|
||||
uci.set('network', sid, 'preshared_key', pconf.peer_presharedkey);
|
||||
uci.set('network', sid, 'allowed_ips', pconf.peer_allowedips);
|
||||
uci.set('network', sid, 'persistent_keepalive', pconf.peer_persistentkeepalive);
|
||||
|
||||
if (config.peer_endpoint) {
|
||||
uci.set('network', sid, 'endpoint_host', config.peer_endpoint[0]);
|
||||
uci.set('network', sid, 'endpoint_port', config.peer_endpoint[1]);
|
||||
if (pconf.peer_endpoint) {
|
||||
uci.set('network', sid, 'endpoint_host', pconf.peer_endpoint[0]);
|
||||
uci.set('network', sid, 'endpoint_port', pconf.peer_endpoint[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return s.map.save(null, true);
|
||||
|
@ -382,6 +395,7 @@ return network.registerProtocol('wireguard', {
|
|||
else {
|
||||
return getPublicAndPrivateKeyFromPrivate(config.interface_privatekey).then(function(keypair) {
|
||||
var sid = uci.add('network', 'wireguard_' + s.section);
|
||||
var pub = s.formvalue(s.section, 'public_key');
|
||||
|
||||
uci.sections('network', 'wireguard_' + s.section, function(peer) {
|
||||
if (peer.public_key == keypair.pub)
|
||||
|
@ -391,9 +405,17 @@ return network.registerProtocol('wireguard', {
|
|||
uci.set('network', sid, 'description', comment || _('Imported peer configuration'));
|
||||
uci.set('network', sid, 'public_key', keypair.pub);
|
||||
uci.set('network', sid, 'private_key', keypair.priv);
|
||||
uci.set('network', sid, 'preshared_key', config.peer_presharedkey);
|
||||
uci.set('network', sid, 'allowed_ips', config.peer_allowedips);
|
||||
uci.set('network', sid, 'persistent_keepalive', config.peer_persistentkeepalive);
|
||||
|
||||
for (var i = 0; i < config.peers.length; i++) {
|
||||
var pconf = config.peers[i];
|
||||
|
||||
if (pconf.peer_publickey == pub) {
|
||||
uci.set('network', sid, 'preshared_key', pconf.peer_presharedkey);
|
||||
uci.set('network', sid, 'allowed_ips', pconf.peer_allowedips);
|
||||
uci.set('network', sid, 'persistent_keepalive', pconf.peer_persistentkeepalive);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return s.map.save(null, true);
|
||||
}).then(function() {
|
||||
|
@ -481,7 +503,7 @@ return network.registerProtocol('wireguard', {
|
|||
nodes.appendChild(E('button', {
|
||||
'class': 'btn',
|
||||
'click': ui.createHandlerFn(this, 'handleConfigImport', 'peer')
|
||||
}, [ _('Import peer configuration…') ]));
|
||||
}, [ _('Import configuration as peer…') ]));
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue