luci-proto-wireguard: client qr code generation
Signed-off-by: lvoegl <lvoegl@tdt.de>
This commit is contained in:
parent
d98935c45b
commit
8530232f51
3 changed files with 90 additions and 1 deletions
17
applications/luci-app-wireguard/root/usr/libexec/rpcd/luci.wireguard
Normal file → Executable file
17
applications/luci-app-wireguard/root/usr/libexec/rpcd/luci.wireguard
Normal file → Executable file
|
@ -4,6 +4,7 @@ local json = require "luci.jsonc"
|
||||||
local sys = require "luci.sys"
|
local sys = require "luci.sys"
|
||||||
local io = require "io"
|
local io = require "io"
|
||||||
local uci = require "uci"
|
local uci = require "uci"
|
||||||
|
local fs = require "nixio.fs"
|
||||||
|
|
||||||
local methods = {
|
local methods = {
|
||||||
generateKeyPair = {
|
generateKeyPair = {
|
||||||
|
@ -14,6 +15,22 @@ local methods = {
|
||||||
return {keys = {priv = prv, pub = pub}}
|
return {keys = {priv = prv, pub = pub}}
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
generateQrCode = {
|
||||||
|
args = {privkey = "privkey"},
|
||||||
|
call = function(args)
|
||||||
|
local qr_code
|
||||||
|
|
||||||
|
if fs.access("/usr/bin/qrencode") then
|
||||||
|
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"
|
||||||
|
|
||||||
|
qr_code = sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- '" .. qr_enc .. "' 2>/dev/null")
|
||||||
|
end
|
||||||
|
|
||||||
|
return {qr_code = qr_code}
|
||||||
|
end
|
||||||
|
},
|
||||||
getWgInstances = {
|
getWgInstances = {
|
||||||
call = function()
|
call = function()
|
||||||
local data = {}
|
local data = {}
|
||||||
|
|
|
@ -11,6 +11,13 @@ var generateKey = rpc.declare({
|
||||||
expect: { keys: {} }
|
expect: { keys: {} }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var generateQrCode = rpc.declare({
|
||||||
|
object: 'luci.wireguard',
|
||||||
|
method: 'generateQrCode',
|
||||||
|
params: ['privkey'],
|
||||||
|
expect: { qr_code: '' }
|
||||||
|
});
|
||||||
|
|
||||||
function validateBase64(section_id, value) {
|
function validateBase64(section_id, value) {
|
||||||
if (value.length == 0)
|
if (value.length == 0)
|
||||||
return true;
|
return true;
|
||||||
|
@ -24,6 +31,15 @@ function validateBase64(section_id, value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findSection(sections, name) {
|
||||||
|
for (var i = 0; i < sections.length; i++) {
|
||||||
|
var section = sections[i];
|
||||||
|
if (section['.name'] == name) return section;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return network.registerProtocol('wireguard', {
|
return network.registerProtocol('wireguard', {
|
||||||
getI18n: function() {
|
getI18n: function() {
|
||||||
return _('WireGuard VPN');
|
return _('WireGuard VPN');
|
||||||
|
@ -131,6 +147,59 @@ return network.registerProtocol('wireguard', {
|
||||||
o.datatype = 'string';
|
o.datatype = 'string';
|
||||||
o.optional = true;
|
o.optional = true;
|
||||||
|
|
||||||
|
o = ss.option(form.Value, 'description', _('QR-Code'));
|
||||||
|
o.render = L.bind(function (view, section_id) {
|
||||||
|
var sections = uci.sections('network');
|
||||||
|
var serverName = this.getIfname();
|
||||||
|
var server = findSection(sections, serverName);
|
||||||
|
|
||||||
|
var description = '%s:<br />• [Interface] %s<br />• [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')
|
||||||
|
);
|
||||||
|
|
||||||
|
return E('div', { 'class': 'cbi-value' }, [
|
||||||
|
E('label', { 'class': 'cbi-value-title' }, _('QR-Code')),
|
||||||
|
E('div', {
|
||||||
|
'style': 'display: flex; flex-direction: column; align-items: baseline;',
|
||||||
|
'id': 'qr-' + section_id
|
||||||
|
}, [
|
||||||
|
E('button', {
|
||||||
|
'class': 'btn cbi-button cbi-button-apply',
|
||||||
|
'click': ui.createHandlerFn(this, function (publicKey, section_id) {
|
||||||
|
var qrDiv = document.getElementById('qr-' + section_id);
|
||||||
|
var qrEl = qrDiv.querySelector('value');
|
||||||
|
var qrBtn = qrDiv.querySelector('button');
|
||||||
|
var qrencodeErr = '<b>%q</b>'.format(
|
||||||
|
_('For QR-Code support please install the qrencode package!'));
|
||||||
|
|
||||||
|
if (qrEl.innerHTML != '' && qrEl.innerHTML != qrencodeErr) {
|
||||||
|
qrEl.innerHTML = '';
|
||||||
|
qrBtn.innerHTML = _('Generate New QR-Code')
|
||||||
|
} else {
|
||||||
|
qrEl.innerHTML = _('Loading QR-Code...');
|
||||||
|
|
||||||
|
generateQrCode(publicKey).then(function (qrCode) {
|
||||||
|
if (qrCode == '') {
|
||||||
|
qrEl.innerHTML = qrencodeErr;
|
||||||
|
} else {
|
||||||
|
qrEl.innerHTML = qrCode;
|
||||||
|
qrBtn.innerHTML = _('Hide QR-Code');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, server.private_key, section_id)
|
||||||
|
}, _('Generate new QR-Code')),
|
||||||
|
E('value', {
|
||||||
|
'class': 'cbi-section',
|
||||||
|
'style': 'margin: 0;'
|
||||||
|
}),
|
||||||
|
E('div', { 'class': 'cbi-value-description' }, description)
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
}, this);
|
||||||
|
|
||||||
o = ss.option(form.Value, 'public_key', _('Public Key'), _('Required. Base64-encoded public key of peer.'));
|
o = ss.option(form.Value, 'public_key', _('Public Key'), _('Required. Base64-encoded public key of peer.'));
|
||||||
o.validate = validateBase64;
|
o.validate = validateBase64;
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
"description": "Grant access to LuCI Wireguard procedures",
|
"description": "Grant access to LuCI Wireguard procedures",
|
||||||
"write": {
|
"write": {
|
||||||
"ubus": {
|
"ubus": {
|
||||||
"luci.wireguard": [ "generateKeyPair" ]
|
"luci.wireguard": [
|
||||||
|
"generateKeyPair",
|
||||||
|
"generateQrCode"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue