From: Jo-Philipp Wich Date: Mon, 1 Aug 2022 11:00:31 +0000 (+0200) Subject: luci-proto-wireguard: handle multiple peers in imported configuration X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=18e6040bb86f3cbc1117250ef7cb6d8319a550e9;p=project%2Fluci.git 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 (cherry picked from commit 94bfa33452ad7db683e9f47ea9921e92b5175558) --- diff --git a/protocols/luci-proto-wireguard/htdocs/luci-static/resources/protocol/wireguard.js b/protocols/luci-proto-wireguard/htdocs/luci-static/resources/protocol/wireguard.js index 3e33517551..900a7cb745 100644 --- a/protocols/luci-proto-wireguard/htdocs/luci-static/resources/protocol/wireguard.js +++ b/protocols/luci-proto-wireguard/htdocs/luci-static/resources/protocol/wireguard.js @@ -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'); - } - else { - config.peer_allowedips = [ '0.0.0.0/0', '::/0' ]; - } + 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 (config.peer_endpoint) { - var host_port = config.peer_endpoint.match(/^\[([a-fA-F0-9:]+)\]:(\d+)$/) || config.peer_endpoint.match(/^(.+):(\d+)$/); + 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'); + 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] ]; - } + pconf.peer_endpoint = [ host_port[1], host_port[2] ]; + } - if (config.peer_persistentkeepalive == 'off' || config.peer_persistentkeepalive == '0') - delete config.peer_persistentkeepalive; + if (pconf.peer_persistentkeepalive == 'off' || pconf.peer_persistentkeepalive == '0') + delete pconf.peer_persistentkeepalive; - if (!stubValidator.apply('port', config.peer_persistentkeepalive || '0')) - return _('PersistentKeepAlive setting is invalid'); + if (!stubValidator.apply('port', pconf.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); - - uci.sections('network', 'wireguard_' + s.section, function(peer) { - if (peer.public_key == config.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); - - if (config.peer_endpoint) { - uci.set('network', sid, 'endpoint_host', config.peer_endpoint[0]); - uci.set('network', sid, 'endpoint_port', config.peer_endpoint[1]); + 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 == pconf.peer_publickey) + uci.remove('network', peer['.name']); + }); + + 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 (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; };