3 local json = require "luci.jsonc"
4 local sys = require "luci.sys"
5 local io = require "io"
6 local uci = require "uci"
7 local fs = require "nixio.fs"
12 local prv = sys.exec("wg genkey 2>/dev/null"):sub(1, -2)
13 local pub = sys.exec("echo '" .. prv .. "' | wg pubkey 2>/dev/null"):sub(1, -2)
15 return {keys = {priv = prv, pub = pub}}
19 args = {privkey = "privkey", psk = "psk", allowed_ips = {"allowed_ips"}},
23 if fs.access("/usr/bin/qrencode") then
25 local listen_port = args.listen_port
26 local allowed_ips = args.allowed_ips
28 local pubkey = sys.exec("echo '" .. args.privkey .. "' | wg pubkey 2>/dev/null"):sub(1, -2)
29 local client_privkey = sys.exec("wg genkey 2>/dev/null"):sub(1, -2)
33 "PrivateKey = " .. client_privkey,
38 "PublicKey = " .. pubkey,
41 if not allowed_ips or next(allowed_ips) == nil then
42 allowed_ips = {"0.0.0.0/0", "::/0"}
44 table.insert(peer_qr, "AllowedIPs = " .. table.concat(allowed_ips, ", "))
47 table.insert(peer_qr, "PresharedKey = " .. psk)
50 qr_enc = table.concat(iface_qr, "\n") .. "\n\n" .. table.concat(peer_qr, "\n")
51 qr_code = sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- '" .. qr_enc .. "' 2>/dev/null")
54 return {qr_code = qr_code}
60 local last_device = ""
63 local wg_dump = io.popen("wg show all dump 2>/dev/null")
66 for line in wg_dump:lines() do
67 local line = string.split(line, "\t")
68 if not (last_device == line[1]) then
73 listen_port = line[4],
77 if not line[3] or line[3] == "" or line[3] == "(none)" then
78 qr_pubkey[line[1]] = ""
80 qr_pubkey[line[1]] = "PublicKey = " .. line[3]
84 local cur = uci.cursor()
88 "wireguard_" .. line[1],
90 if s.public_key == line[2] then
91 peer_name = s.description
100 public_key = line[2],
103 latest_handshake = line[6],
104 transfer_rx = line[7],
105 transfer_tx = line[8],
106 persistent_keepalive = line[9]
110 if not (line[4] == "(none)") then
112 for ipkey, ipvalue in pairs(string.split(line[5], ",")) do
114 table.insert(data[line[1]].peers[peer_name]["allowed_ips"], ipvalue)
127 local function parseInput()
128 local parse = json.new()
132 local chunk = io.read(4096)
135 elseif not done and not err then
136 done, err = parse:parse(chunk)
141 print(json.stringify({error = err or "Incomplete input"}))
148 local function validateArgs(func, uargs)
149 local method = methods[func]
151 print(json.stringify({error = "Method not found"}))
155 if type(uargs) ~= "table" then
156 print(json.stringify({error = "Invalid arguments"}))
160 uargs.ubus_rpc_session = nil
163 local margs = method.args or {}
164 for k, v in pairs(uargs) do
165 if margs[k] == nil or (v ~= nil and type(v) ~= type(margs[k])) then
166 print(json.stringify({error = "Invalid arguments"}))
174 if arg[1] == "list" then
175 local _, method, rv = nil, nil, {}
176 for _, method in pairs(methods) do
177 rv[_] = method.args or {}
179 print((json.stringify(rv):gsub(":%[%]", ":{}")))
180 elseif arg[1] == "call" then
181 local args = parseInput()
182 local method = validateArgs(arg[2], args)
183 local result, code = method.call(args)
184 print((json.stringify(result):gsub("^%[%]$", "{}")))