Rewrite the wireguard rpcd plugin in ucode to prevent an implicit dependency on the LuCI Lua runtime. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
105 lines
2.3 KiB
Text
105 lines
2.3 KiB
Text
// Copyright 2022 Jo-Philipp Wich <jo@mein.io>
|
|
// Licensed to the public under the Apache License 2.0.
|
|
|
|
'use strict';
|
|
|
|
import { cursor } from 'uci';
|
|
import { popen } from 'fs';
|
|
|
|
|
|
function shellquote(s) {
|
|
return `'${replace(s ?? '', "'", "'\\''")}'`;
|
|
}
|
|
|
|
function command(cmd) {
|
|
return trim(popen(cmd)?.read?.('all'));
|
|
}
|
|
|
|
|
|
const methods = {
|
|
generatePsk: {
|
|
call: function() {
|
|
return { psk: command('wg genpsk 2>/dev/null') };
|
|
}
|
|
},
|
|
|
|
generateKeyPair: {
|
|
call: function() {
|
|
const priv = command('wg genkey 2>/dev/null');
|
|
const pub = command(`echo ${shellquote(priv)} | wg pubkey 2>/dev/null`);
|
|
|
|
return { keys: { priv, pub } };
|
|
}
|
|
},
|
|
|
|
getPublicAndPrivateKeyFromPrivate: {
|
|
args: { privkey: "privkey" },
|
|
call: function(req) {
|
|
const priv = req.args?.privkey;
|
|
const pub = command(`echo ${shellquote(priv)} | wg pubkey 2>/dev/null`);
|
|
|
|
return { keys: { priv, pub } };
|
|
}
|
|
},
|
|
|
|
getWgInstances: {
|
|
call: function() {
|
|
const data = {};
|
|
let last_device;
|
|
let qr_pubkey = {};
|
|
|
|
const uci = cursor();
|
|
const wg_dump = popen("wg show all dump 2>/dev/null");
|
|
|
|
if (wg_dump) {
|
|
for (let line = wg_dump.read('line'); length(line); line = wg_dump.read('line')) {
|
|
const record = split(rtrim(line, '\n'), '\t');
|
|
|
|
if (last_device != record[0]) {
|
|
last_device = record[0];
|
|
data[last_device] = {
|
|
name: last_device,
|
|
public_key: record[2],
|
|
listen_port: record[3],
|
|
fwmark: record[4],
|
|
peers: []
|
|
};
|
|
|
|
if (!length(record[2]) || record[2] == '(none)')
|
|
qr_pubkey[last_device] = '';
|
|
else
|
|
qr_pubkey[last_device] = `PublicKey = ${record[2]}`;
|
|
}
|
|
else {
|
|
let peer_name;
|
|
|
|
uci.foreach('network', `wireguard_${last_device}`, (s) => {
|
|
if (s.public_key == record[1])
|
|
peer_name = s.description;
|
|
});
|
|
|
|
const peer = {
|
|
name: peer_name,
|
|
public_key: record[1],
|
|
endpoint: record[3],
|
|
allowed_ips: [],
|
|
latest_handshake: record[5],
|
|
transfer_rx: record[6],
|
|
transfer_tx: record[7],
|
|
persistent_keepalive: record[8]
|
|
};
|
|
|
|
if (record[3] != '(none)' && length(record[4]))
|
|
push(peer.allowed_ips, ...split(record[4], ','));
|
|
|
|
push(data[last_device].peers, peer);
|
|
}
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
}
|
|
};
|
|
|
|
return { 'luci.wireguard': methods };
|