luci-proto-wireguard: add more options to qr code
authorlvoegl <[email protected]>
Fri, 10 Sep 2021 12:01:53 +0000 (14:01 +0200)
committerLukas Voegl <[email protected]>
Fri, 17 Sep 2021 12:22:54 +0000 (14:22 +0200)
Signed-off-by: lvoegl <[email protected]>
applications/luci-app-wireguard/root/usr/libexec/rpcd/luci.wireguard
protocols/luci-proto-wireguard/htdocs/luci-static/resources/protocol/wireguard.js

index fd3b4c8c44d64e86592f93b3827c3a8ca67bb420..94374b07d7f4d31e097f14bade299aec7f09ed66 100755 (executable)
@@ -16,15 +16,38 @@ local methods = {
                end
        },
        generateQrCode = {
-               args = {privkey = "privkey"},
+               args = {privkey = "privkey", psk = "psk", allowed_ips = {"allowed_ips"}},
                call = function(args)
                        local qr_code
 
                        if fs.access("/usr/bin/qrencode") then
+                               local psk = args.psk
+                               local listen_port = args.listen_port
+                               local allowed_ips = args.allowed_ips
+
                                local pubkey = sys.exec("echo '" .. args.privkey .. "' | wg pubkey 2>/dev/null"):sub(1, -2)
                                local client_privkey = sys.exec("wg genkey 2>/dev/null"):sub(1, -2)
-                               local qr_enc = "[Interface]\nPrivateKey = " .. client_privkey .. "\n[Peer]\nPublicKey = " .. pubkey .. "\nAllowedIPs = 0.0.0.0/0, ::/0"
 
+                               local iface_qr = {
+                                       "[Interface]",
+                                       "PrivateKey = " .. client_privkey,
+                               }
+
+                               local peer_qr = {
+                                       "[Peer]",
+                                       "PublicKey = " .. pubkey,
+                               }
+
+                               if not allowed_ips or next(allowed_ips) == nil then
+                                       allowed_ips = {"0.0.0.0/0", "::/0"}
+                               end
+                               table.insert(peer_qr, "AllowedIPs = " .. table.concat(allowed_ips, ", "))
+
+                               if psk then
+                                       table.insert(peer_qr, "PresharedKey = " .. psk)
+                               end
+
+                               qr_enc = table.concat(iface_qr, "\n") .. "\n\n" .. table.concat(peer_qr, "\n")
                                qr_code = sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- '" .. qr_enc .. "' 2>/dev/null")
                        end
 
index 68dfb5bae69d4469aef105b659525bdf803fbca9..51f9accf4600d324db4d844b5d1a4e3097d50f19 100644 (file)
@@ -14,7 +14,7 @@ var generateKey = rpc.declare({
 var generateQrCode = rpc.declare({
        object: 'luci.wireguard',
        method: 'generateQrCode',
-       params: ['privkey'],
+       params: ['privkey', 'psk', 'allowed_ips'],
        expect: { qr_code: '' }
 });
 
@@ -40,6 +40,15 @@ function findSection(sections, name) {
        return null;
 }
 
+function generateDescription(name, texts) {
+       return E('li', { 'style': 'color: inherit;' }, [
+               E('span', name),
+               E('ul', texts.map(function (text) {
+                       return E('li', { 'style': 'color: inherit;' }, text);
+               }))
+       ]);
+}
+
 return network.registerProtocol('wireguard', {
        getI18n: function() {
                return _('WireGuard VPN');
@@ -150,14 +159,28 @@ return network.registerProtocol('wireguard', {
                o = ss.option(form.Value, 'description', _('QR-Code'));
                o.render = L.bind(function (view, section_id) {
                        var sections = uci.sections('network');
+                       var client = findSection(sections, section_id);
                        var serverName = this.getIfname();
                        var server = findSection(sections, serverName);
 
-                       var description = '%s:<br />&#8226;&#160;[Interface] %s<br />&#8226;&#160;[Peer] %s'.format(
-                               _('The QR-Code works per wg interface, it will be refreshed with every button click and transfers the following information'),
-                               _('A random, on the fly generated "PrivateKey", the key will not be saved on the router'),
-                               _('The "PublicKey" of that wg interface and the "AllowedIPs" with the default of "0.0.0.0/0, ::/0" to allow sending traffic to any IPv4 and IPv6 address')
-                       );
+                       var interfaceTexts = [
+                               'PrivateKey: ' + _('A random, on the fly generated "PrivateKey", the key will not be saved on the router')
+                       ];
+
+                       var peerTexts = [
+                               'PublicKey: ' + _('The "PublicKey" of that wg interface'),
+                               'AllowedIPs: ' + _('The list of this client\'s "AllowedIPs" or "0.0.0.0/0, ::/0" if not configured'),
+                               'PresharedKey: ' + _('If available, the client\'s "PresharedKey"')
+                       ];
+
+                       var description = [
+                               E('span', '%q<br>%q'.format(_('If there are any unsaved changes for this client, please save the configuration before generating a QR-Code'),
+                                       _('The QR-Code works per wg interface, it will be refreshed with every button click and transfers the following information:'))),
+                               E('ul', [
+                                       generateDescription('[Interface]', interfaceTexts),
+                                       generateDescription('[Peer]', peerTexts)
+                               ])
+                       ];
 
                        return E('div', { 'class': 'cbi-value' }, [
                                E('label', { 'class': 'cbi-value-title' }, _('QR-Code')),
@@ -167,7 +190,7 @@ return network.registerProtocol('wireguard', {
                                }, [
                                        E('button', {
                                                'class': 'btn cbi-button cbi-button-apply',
-                                               'click': ui.createHandlerFn(this, function (publicKey, section_id) {
+                                               'click': ui.createHandlerFn(this, function (server, client, section_id) {
                                                        var qrDiv = document.getElementById('qr-' + section_id);
                                                        var qrEl = qrDiv.querySelector('value');
                                                        var qrBtn = qrDiv.querySelector('button');
@@ -180,16 +203,17 @@ return network.registerProtocol('wireguard', {
                                                        } else {
                                                                qrEl.innerHTML = _('Loading QR-Code...');
 
-                                                               generateQrCode(publicKey).then(function (qrCode) {
-                                                                       if (qrCode == '') {
+                                                               generateQrCode(server.private_key, client.preshared_key,
+                                                                       client.allowed_ips).then(function (qrCode) {
+                                                                               if (qrCode == '') {
                                                                                        qrEl.innerHTML = qrencodeErr;
-                                                                       } else {
-                                                                               qrEl.innerHTML = qrCode;
-                                                                               qrBtn.innerHTML = _('Hide QR-Code');
-                                                                       }
-                                                               });
+                                                                               } else {
+                                                                                       qrEl.innerHTML = qrCode;
+                                                                                       qrBtn.innerHTML = _('Hide QR-Code');
+                                                                               }
+                                                                       });
                                                        }
-                                               }, server.private_key, section_id)
+                                               }, server, client, section_id)
                                        }, _('Generate new QR-Code')),
                                        E('value', {
                                                'class': 'cbi-section',