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>
This commit is contained in:
parent
abd9125fbf
commit
94bfa33452
1 changed files with 68 additions and 46 deletions
|
@ -253,20 +253,26 @@ return network.registerProtocol('wireguard', {
|
||||||
ss.parseConfig = function(data) {
|
ss.parseConfig = function(data) {
|
||||||
var lines = String(data).split(/(\r?\n)+/),
|
var lines = String(data).split(/(\r?\n)+/),
|
||||||
section = null,
|
section = null,
|
||||||
config = {};
|
config = { peers: [] },
|
||||||
|
s;
|
||||||
|
|
||||||
for (var i = 0; i < lines.length; i++) {
|
for (var i = 0; i < lines.length; i++) {
|
||||||
var line = lines[i].replace(/#.*$/, '').trim();
|
var line = lines[i].replace(/#.*$/, '').trim();
|
||||||
|
|
||||||
if (line.match(/^\[(\w+)\]$/)) {
|
if (line.match(/^\[(\w+)\]$/)) {
|
||||||
section = RegExp.$1.toLowerCase();
|
section = RegExp.$1.toLowerCase();
|
||||||
|
|
||||||
|
if (section == 'peer')
|
||||||
|
config.peers.push(s = {});
|
||||||
|
else
|
||||||
|
s = config;
|
||||||
}
|
}
|
||||||
else if (section && line.match(/^(\w+)\s*=\s*(.+)$/)) {
|
else if (section && line.match(/^(\w+)\s*=\s*(.+)$/)) {
|
||||||
var key = RegExp.$1,
|
var key = RegExp.$1,
|
||||||
val = RegExp.$2.trim();
|
val = RegExp.$2.trim();
|
||||||
|
|
||||||
if (val.length)
|
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'))
|
if (!stubValidator.apply('port', config.interface_listenport || '0'))
|
||||||
return _('ListenPort setting is invalid');
|
return _('ListenPort setting is invalid');
|
||||||
|
|
||||||
if (config.peer_publickey != null && validateBase64(null, config.peer_publickey) !== true)
|
for (var i = 0; i < config.peers.length; i++) {
|
||||||
|
var pconf = config.peers[i];
|
||||||
|
|
||||||
|
if (pconf.peer_publickey != null && validateBase64(null, pconf.peer_publickey) !== true)
|
||||||
return _('PublicKey setting is invalid');
|
return _('PublicKey setting is invalid');
|
||||||
|
|
||||||
if (config.peer_presharedkey != null && validateBase64(null, config.peer_presharedkey) !== true)
|
if (pconf.peer_presharedkey != null && validateBase64(null, pconf.peer_presharedkey) !== true)
|
||||||
return _('PresharedKey setting is invalid');
|
return _('PresharedKey setting is invalid');
|
||||||
|
|
||||||
if (config.peer_allowedips) {
|
if (pconf.peer_allowedips) {
|
||||||
config.peer_allowedips = config.peer_allowedips.split(/[, ]+/);
|
pconf.peer_allowedips = pconf.peer_allowedips.split(/[, ]+/);
|
||||||
|
|
||||||
for (var i = 0; i < config.peer_allowedips.length; i++)
|
for (var j = 0; j < pconf.peer_allowedips.length; j++)
|
||||||
if (!stubValidator.apply('ipaddr', config.peer_allowedips[i]))
|
if (!stubValidator.apply('ipaddr', pconf.peer_allowedips[j]))
|
||||||
return _('AllowedIPs setting is invalid');
|
return _('AllowedIPs setting is invalid');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
config.peer_allowedips = [ '0.0.0.0/0', '::/0' ];
|
pconf.peer_allowedips = [ '0.0.0.0/0', '::/0' ];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.peer_endpoint) {
|
if (pconf.peer_endpoint) {
|
||||||
var host_port = config.peer_endpoint.match(/^\[([a-fA-F0-9:]+)\]:(\d+)$/) || config.peer_endpoint.match(/^(.+):(\d+)$/);
|
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]))
|
if (!host_port || !stubValidator.apply('host', host_port[1]) || !stubValidator.apply('port', host_port[2]))
|
||||||
return _('Endpoint setting is invalid');
|
return _('Endpoint setting is invalid');
|
||||||
|
|
||||||
config.peer_endpoint = [ host_port[1], host_port[2] ];
|
pconf.peer_endpoint = [ host_port[1], host_port[2] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.peer_persistentkeepalive == 'off' || config.peer_persistentkeepalive == '0')
|
if (pconf.peer_persistentkeepalive == 'off' || pconf.peer_persistentkeepalive == '0')
|
||||||
delete config.peer_persistentkeepalive;
|
delete pconf.peer_persistentkeepalive;
|
||||||
|
|
||||||
if (!stubValidator.apply('port', config.peer_persistentkeepalive || '0'))
|
if (!stubValidator.apply('port', pconf.peer_persistentkeepalive || '0'))
|
||||||
return _('PersistentKeepAlive setting is invalid');
|
return _('PersistentKeepAlive setting is invalid');
|
||||||
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
@ -356,22 +366,25 @@ return network.registerProtocol('wireguard', {
|
||||||
s.getOption('dns').getUIElement(s.section).setValue(config.interface_dns);
|
s.getOption('dns').getUIElement(s.section).setValue(config.interface_dns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < config.peers.length; i++) {
|
||||||
|
var pconf = config.peers[i];
|
||||||
var sid = uci.add('network', 'wireguard_' + s.section);
|
var sid = uci.add('network', 'wireguard_' + s.section);
|
||||||
|
|
||||||
uci.sections('network', 'wireguard_' + s.section, function(peer) {
|
uci.sections('network', 'wireguard_' + s.section, function(peer) {
|
||||||
if (peer.public_key == config.peer_publickey)
|
if (peer.public_key == pconf.peer_publickey)
|
||||||
uci.remove('network', peer['.name']);
|
uci.remove('network', peer['.name']);
|
||||||
});
|
});
|
||||||
|
|
||||||
uci.set('network', sid, 'description', comment || _('Imported peer configuration'));
|
uci.set('network', sid, 'description', comment || _('Imported peer configuration'));
|
||||||
uci.set('network', sid, 'public_key', config.peer_publickey);
|
uci.set('network', sid, 'public_key', pconf.peer_publickey);
|
||||||
uci.set('network', sid, 'preshared_key', config.peer_presharedkey);
|
uci.set('network', sid, 'preshared_key', pconf.peer_presharedkey);
|
||||||
uci.set('network', sid, 'allowed_ips', config.peer_allowedips);
|
uci.set('network', sid, 'allowed_ips', pconf.peer_allowedips);
|
||||||
uci.set('network', sid, 'persistent_keepalive', config.peer_persistentkeepalive);
|
uci.set('network', sid, 'persistent_keepalive', pconf.peer_persistentkeepalive);
|
||||||
|
|
||||||
if (config.peer_endpoint) {
|
if (pconf.peer_endpoint) {
|
||||||
uci.set('network', sid, 'endpoint_host', config.peer_endpoint[0]);
|
uci.set('network', sid, 'endpoint_host', pconf.peer_endpoint[0]);
|
||||||
uci.set('network', sid, 'endpoint_port', config.peer_endpoint[1]);
|
uci.set('network', sid, 'endpoint_port', pconf.peer_endpoint[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.map.save(null, true);
|
return s.map.save(null, true);
|
||||||
|
@ -382,6 +395,7 @@ return network.registerProtocol('wireguard', {
|
||||||
else {
|
else {
|
||||||
return getPublicAndPrivateKeyFromPrivate(config.interface_privatekey).then(function(keypair) {
|
return getPublicAndPrivateKeyFromPrivate(config.interface_privatekey).then(function(keypair) {
|
||||||
var sid = uci.add('network', 'wireguard_' + s.section);
|
var sid = uci.add('network', 'wireguard_' + s.section);
|
||||||
|
var pub = s.formvalue(s.section, 'public_key');
|
||||||
|
|
||||||
uci.sections('network', 'wireguard_' + s.section, function(peer) {
|
uci.sections('network', 'wireguard_' + s.section, function(peer) {
|
||||||
if (peer.public_key == keypair.pub)
|
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, 'description', comment || _('Imported peer configuration'));
|
||||||
uci.set('network', sid, 'public_key', keypair.pub);
|
uci.set('network', sid, 'public_key', keypair.pub);
|
||||||
uci.set('network', sid, 'private_key', keypair.priv);
|
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);
|
for (var i = 0; i < config.peers.length; i++) {
|
||||||
uci.set('network', sid, 'persistent_keepalive', config.peer_persistentkeepalive);
|
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);
|
return s.map.save(null, true);
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
|
@ -481,7 +503,7 @@ return network.registerProtocol('wireguard', {
|
||||||
nodes.appendChild(E('button', {
|
nodes.appendChild(E('button', {
|
||||||
'class': 'btn',
|
'class': 'btn',
|
||||||
'click': ui.createHandlerFn(this, 'handleConfigImport', 'peer')
|
'click': ui.createHandlerFn(this, 'handleConfigImport', 'peer')
|
||||||
}, [ _('Import peer configuration…') ]));
|
}, [ _('Import configuration as peer…') ]));
|
||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue