Big code refactoring #10
9
.vscode/c_cpp_properties.json
vendored
9
.vscode/c_cpp_properties.json
vendored
@ -16,6 +16,15 @@
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "macos-clang-x64"
|
||||
},
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/node_modules/node-addon-api",
|
||||
"/usr/include/node",
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/addon"
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
@ -10,6 +10,7 @@ extern "C" {
|
||||
#include <arpa/inet.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
std::string getWireguardVersion() {
|
||||
return "Kernel";
|
||||
@ -96,6 +97,7 @@ void WireguardConfig::getWireguardConfig() {
|
||||
memset(buf, 0, INET6_ADDRSTRLEN + 1);
|
||||
if (allowedip->family == AF_INET) inet_ntop(AF_INET, &allowedip->ip4, buf, INET6_ADDRSTRLEN);
|
||||
else if (allowedip->family == AF_INET6) inet_ntop(AF_INET6, &allowedip->ip6, buf, INET6_ADDRSTRLEN);
|
||||
else continue;
|
||||
PeerConfig.allowedIPs.push_back(std::string(buf).append("/").append(std::to_string(allowedip->cidr)));
|
||||
}
|
||||
}
|
||||
@ -105,12 +107,11 @@ void WireguardConfig::getWireguardConfig() {
|
||||
|
||||
void WireguardConfig::setWireguardConfig() {
|
||||
int status;
|
||||
if (this->name.length() == 0) throw std::string("Set wireguard name!");
|
||||
else if (this->name.length() > IFNAMSIZ) throw std::string("Wireguard interface name is long, max name length is ").append(std::to_string(IFNAMSIZ));
|
||||
if (this->name.length() > IFNAMSIZ) throw std::string("Wireguard interface name is long, max name length is ").append(std::to_string(IFNAMSIZ));
|
||||
else if (!(WireguardDevices().exist(this->name)) && (status = wg_add_device(this->name.c_str())) < 0) throw std::string("Unable to create Wireguard interface, code: ").append(std::to_string(status));
|
||||
if (this->privateKey.length() != Base64WgKeyLength) throw std::string("Set Wireguard interface private key!");
|
||||
|
||||
auto wgConfig = (wg_device*)malloc(sizeof(wg_device));
|
||||
auto wgConfig = new wg_device({});
|
||||
if (!wgConfig) throw std::string("Cannot alloc memory to set interface configuration!");
|
||||
strncpy(wgConfig->name, this->name.c_str(), this->name.length());
|
||||
|
||||
@ -135,8 +136,7 @@ void WireguardConfig::setWireguardConfig() {
|
||||
}
|
||||
|
||||
for (auto &PeerConfig : this->Peers) {
|
||||
wg_peer* peer;
|
||||
peer = (wg_peer*)malloc(sizeof(wg_peer));
|
||||
auto peer = new wg_peer({});
|
||||
peer->flags = wg_peer_flags::WGPEER_HAS_PUBLIC_KEY;
|
||||
wgKeys::stringToKey(peer->public_key, PeerConfig.first);
|
||||
if (PeerConfig.second.removeMe) peer->flags = (wg_peer_flags)(peer->flags|wg_peer_flags::WGPEER_REMOVE_ME);
|
||||
@ -158,16 +158,16 @@ void WireguardConfig::setWireguardConfig() {
|
||||
begin = &Endpoint[1];
|
||||
end = strchr(Endpoint, ']');
|
||||
if (!end) {
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { free(peer); }
|
||||
free(wgConfig);
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { delete peer; }
|
||||
delete wgConfig;
|
||||
free(Endpoint);
|
||||
throw std::string("Unable to find matching brace of endpoint");
|
||||
return;
|
||||
}
|
||||
*end++ = '\0';
|
||||
if (*end++ != ':' || !*end) {
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { free(peer); }
|
||||
free(wgConfig);
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { delete peer; }
|
||||
delete wgConfig;
|
||||
free(Endpoint);
|
||||
throw std::string("Unable to find port of endpoint");
|
||||
return;
|
||||
@ -176,8 +176,8 @@ void WireguardConfig::setWireguardConfig() {
|
||||
begin = Endpoint;
|
||||
end = strrchr(Endpoint, ':');
|
||||
if (!end || !*(end + 1)) {
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { free(peer); }
|
||||
free(wgConfig);
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { delete peer; }
|
||||
delete wgConfig;
|
||||
free(Endpoint);
|
||||
throw std::string("Unable to find port of endpoint");
|
||||
}
|
||||
@ -192,8 +192,8 @@ void WireguardConfig::setWireguardConfig() {
|
||||
ret == EAI_NODATA ||
|
||||
#endif
|
||||
(retries >= 0 && !retries--)) {
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { free(peer); }
|
||||
free(wgConfig);
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { delete peer; }
|
||||
delete wgConfig;
|
||||
free(Endpoint);
|
||||
fprintf(stderr, "%s: `%s'\n", ret == EAI_SYSTEM ? strerror(errno) : gai_strerror(ret), PeerConfig.second.endpoint.c_str());
|
||||
throw std::string("Unable to resolve endpoint");
|
||||
@ -216,30 +216,29 @@ void WireguardConfig::setWireguardConfig() {
|
||||
}
|
||||
} else {
|
||||
freeaddrinfo(resolved);
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { free(peer); }
|
||||
free(wgConfig);
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { delete peer; }
|
||||
delete wgConfig;
|
||||
free(Endpoint);
|
||||
throw std::string("Neither IPv4 nor IPv6 address found");
|
||||
}
|
||||
|
||||
freeaddrinfo(resolved);
|
||||
// Free memory
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { free(peer); }
|
||||
free(wgConfig);
|
||||
for ((peer) = (wgConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { delete peer; }
|
||||
delete wgConfig;
|
||||
free(Endpoint);
|
||||
}
|
||||
|
||||
// Set allowed IPs
|
||||
if (PeerConfig.second.allowedIPs.size() > 0) {
|
||||
wg_allowedip *newAllowedIP;
|
||||
peer->flags = (wg_peer_flags)(peer->flags|WGPEER_REPLACE_ALLOWEDIPS);
|
||||
for (const auto &Ip : PeerConfig.second.allowedIPs.getIpParsed()) {
|
||||
newAllowedIP = (wg_allowedip*)(malloc(sizeof(wg_allowedip)));
|
||||
auto newAllowedIP = new wg_allowedip({});
|
||||
newAllowedIP->cidr = Ip.Mask;
|
||||
if (Ip.Proto == 6 && inet_pton(AF_INET6, Ip.Address.c_str(), &newAllowedIP->ip6) == 1) newAllowedIP->family = AF_INET6;
|
||||
else if (Ip.Proto == 4 && inet_pton(AF_INET, Ip.Address.c_str(), &newAllowedIP->ip4) == 1) newAllowedIP->family = AF_INET;
|
||||
else {
|
||||
free(newAllowedIP);
|
||||
delete newAllowedIP;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -258,10 +257,10 @@ void WireguardConfig::setWireguardConfig() {
|
||||
|
||||
// Free memory
|
||||
for (wg_peer* peer = wgConfig->first_peer; peer; peer = peer->next_peer) {
|
||||
for (wg_allowedip *newAllowedIP = peer->first_allowedip; newAllowedIP; newAllowedIP = newAllowedIP->next_allowedip) free(newAllowedIP);
|
||||
free(peer);
|
||||
for (wg_allowedip *newAllowedIP = peer->first_allowedip; newAllowedIP; newAllowedIP = newAllowedIP->next_allowedip) delete newAllowedIP;
|
||||
delete peer;
|
||||
}
|
||||
free(wgConfig);
|
||||
delete wgConfig;
|
||||
|
||||
// Return status to tool
|
||||
if (status < 0) throw std::string("Unable to configure settings, code: ").append(std::to_string(status));
|
||||
|
@ -37,14 +37,15 @@ Napi::Object StartAddon(const Napi::Env env, const Napi::Object exports) {
|
||||
|
||||
exports.Set("setConfig", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
const Napi::Env env = info.Env();
|
||||
if (!(info[0].IsObject())) Napi::Error::New(env, "Set wireguard config!").ThrowAsJavaScriptException();
|
||||
try {
|
||||
SetConfig *worker = new SetConfig(env, info[0].ToObject());
|
||||
worker->Queue();
|
||||
return worker->NodePromise.Promise();
|
||||
} catch (std::string &err) {
|
||||
Napi::Error::New(env, err).ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
return env.Undefined();
|
||||
}));
|
||||
|
||||
exports.Set("getConfig", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
|
42
addon/wg.hh
42
addon/wg.hh
@ -72,8 +72,45 @@ class SetConfig : public WireguardConfig, public Promised {
|
||||
|
||||
SetConfig(const Napi::Env &env, const Napi::Object config): Promised(env) {
|
||||
if (!(config.Has("name"))) throw std::string("Set wireguard interface name!");
|
||||
if (!(config.Has("privateKey"))) throw std::string("Set wireguard private key!");
|
||||
if (!(config.Has("privateKey") && config.Get("privateKey").IsString())) throw std::string("Set wireguard private key!");
|
||||
this->name = config.Get("name").ToString().Utf8Value();
|
||||
this->privateKey = config.Get("privateKey").ToString().Utf8Value();
|
||||
if (config.Has("publicKey") && config.Get("publicKey").IsString() && config.Get("publicKey").ToString().Utf8Value().length() == Base64WgKeyLength) this->publicKey = config.Get("publicKey").ToString().Utf8Value();
|
||||
if (config.Has("portListen") && config.Get("portListen").IsNumber() && config.Get("portListen").ToNumber().Int32Value() >= 0) this->portListen = config.Get("portListen").ToNumber().Int32Value();
|
||||
if (config.Has("fwmark") && config.Get("fwmark").IsNumber() && config.Get("fwmark").ToNumber().Int32Value() >= 0) this->fwmark = config.Get("fwmark").ToNumber().Int32Value();
|
||||
|
||||
if (config.Has("address") && config.Get("address").IsArray() && config.Get("address").As<Napi::Array>().Length() > 0) {
|
||||
const Napi::Array Addrs(config.Get("address").As<Napi::Array>());
|
||||
for (unsigned int AddrIndex = 0; AddrIndex < Addrs.Length(); AddrIndex++) {
|
||||
if (!(Addrs[AddrIndex].IsString())) continue;
|
||||
this->interfaceAddress.addIPMask(Addrs[AddrIndex].ToString().Utf8Value());
|
||||
}
|
||||
}
|
||||
|
||||
if (config.Has("peers") && config.Get("peers").IsObject()) {
|
||||
const Napi::Object PeersObject(config.Get("peers").ToObject());
|
||||
const Napi::Array PeersKeys(PeersObject.GetPropertyNames());
|
||||
for (unsigned int peerIndex = 0; peerIndex < PeersKeys.Length(); peerIndex++) {
|
||||
if (!(PeersObject.Get(PeersKeys[peerIndex].ToString()).IsObject())) continue;
|
||||
const std::string publicKey(PeersKeys[peerIndex].ToString().Utf8Value());
|
||||
const Napi::Object peerConfig(PeersObject.Get(publicKey).ToObject());
|
||||
Peer peer;
|
||||
|
||||
if (peerConfig.Has("removeMe") && peerConfig.Get("removeMe").IsBoolean() && peerConfig.Get("removeMe").As<Napi::Boolean>().Value()) peer.removeMe = true;
|
||||
else {
|
||||
if (peerConfig.Has("presharedKey") && peerConfig.Get("presharedKey").IsString() && peerConfig.Get("presharedKey").ToString().Utf8Value().length() == Base64WgKeyLength) peer.presharedKey = peerConfig.Get("presharedKey").ToString().Utf8Value();
|
||||
if (peerConfig.Has("keepInterval") && peerConfig.Get("keepInterval").IsNumber() && peerConfig.Get("keepInterval").ToNumber().Int32Value() > 0) peer.keepInterval = peerConfig.Get("keepInterval").ToNumber().Int32Value();
|
||||
if (peerConfig.Has("endpoint") && peerConfig.Get("endpoint").IsString() && peerConfig.Get("endpoint").ToString().Utf8Value().length() == Base64WgKeyLength) peer.endpoint = peerConfig.Get("endpoint").ToString().Utf8Value();
|
||||
if (peerConfig.Has("allowedIPs") && peerConfig.Get("allowedIPs").IsArray()) {
|
||||
const Napi::Array ips = peerConfig.Get("allowedIPs").As<Napi::Array>();
|
||||
for (unsigned int ipIndex = 0; ipIndex < ips.Length(); ipIndex++) peer.allowedIPs.addIPMask(ips[ipIndex].ToString().Utf8Value());
|
||||
}
|
||||
}
|
||||
|
||||
// Set peer in map
|
||||
this->Peers[publicKey] = peer;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -108,7 +145,6 @@ class GetConfig : public WireguardConfig, public Promised {
|
||||
// Peers
|
||||
const Napi::Object peersObj = Napi::Object::New(env);
|
||||
for (auto &__peer : this->Peers) {
|
||||
std::cout << "script\n";
|
||||
std::string publicKey = __peer.first;
|
||||
if (publicKey.length() != Base64WgKeyLength) continue;
|
||||
const Napi::Object peerConfig = Napi::Object::New(env);
|
||||
@ -124,7 +160,7 @@ class GetConfig : public WireguardConfig, public Promised {
|
||||
|
||||
const Napi::Array ips = Napi::Array::New(env);
|
||||
for (auto &ip : config.allowedIPs) ips.Set(ips.Length(), ip);
|
||||
peersObj.Set("allowedIPs", ips);
|
||||
peerConfig.Set("allowedIPs", ips);
|
||||
|
||||
peersObj.Set(publicKey, peerConfig);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
extern const int wgKeyLength;
|
||||
extern const int Base64WgKeyLength;
|
||||
@ -50,7 +51,7 @@ class IpManeger : public std::vector<std::string> {
|
||||
if (maskStart == std::string::npos) xTop.Address = ip;
|
||||
else {
|
||||
xTop.Address = ip.substr(0, maskStart);
|
||||
xTop.Mask = atoi(ip.substr(maskStart+1).c_str());
|
||||
xTop.Mask = std::stoi(ip.substr(maskStart+1).c_str());
|
||||
if (!isIPv6 && xTop.Mask > 32) throw std::string("Set valid mask to ipv4 address!");
|
||||
}
|
||||
xTop.Proto = isIPv6 ? 6 : 4;
|
||||
@ -63,7 +64,7 @@ class IpManeger : public std::vector<std::string> {
|
||||
IpReference nTop;
|
||||
auto maskStart = ipAddrr->find("/");
|
||||
nTop.Address = ipAddrr->substr(0, maskStart);
|
||||
nTop.Mask = atoi(ipAddrr->substr(maskStart+1).c_str());
|
||||
nTop.Mask = std::stoi(ipAddrr->substr(maskStart+1).c_str());
|
||||
xTops.push_back(nTop);
|
||||
}
|
||||
return xTops;
|
||||
@ -117,6 +118,7 @@ class WireguardConfig {
|
||||
WireguardConfig() {
|
||||
this->portListen = 0;
|
||||
this->fwmark = 0;
|
||||
this->replacePeers = false;
|
||||
}
|
||||
|
||||
/** Wireguard interface name */
|
||||
|
@ -34,8 +34,8 @@
|
||||
},
|
||||
"scripts": {
|
||||
"install": "rebory prebuild",
|
||||
"dev": "rebory build -DP",
|
||||
"test": "rebory build -D && node --no-warnings --loader ts-node/esm src/index_test.js",
|
||||
"dev": "rebory build",
|
||||
"test": "rebory build && node --no-warnings --loader ts-node/esm src/index_test.js",
|
||||
"prepack": "tsc --build --clean && tsc --build",
|
||||
"postpack": "tsc --build --clean"
|
||||
},
|
||||
|
@ -0,0 +1,27 @@
|
||||
import test from "node:test";
|
||||
import { Kernel, SetConfig } from "./wginterface.js";
|
||||
import { presharedKey, privateKey, publicKey } from "./key.js";
|
||||
|
||||
await test("Wireguard interface", async t => {
|
||||
const config: SetConfig = {
|
||||
name: "wg0",
|
||||
privateKey: await privateKey(),
|
||||
address: [
|
||||
"10.66.66.1/32"
|
||||
],
|
||||
peers: {}
|
||||
};
|
||||
|
||||
const peer1 = await privateKey();
|
||||
config.peers[publicKey(peer1)] = {
|
||||
keepInterval: 15,
|
||||
presharedKey: await presharedKey(),
|
||||
allowedIPs: [
|
||||
"10.66.66.2/32"
|
||||
]
|
||||
};
|
||||
|
||||
console.dir(config, { depth: null });
|
||||
await Kernel.setConfig(config);
|
||||
console.dir(await Kernel.getConfig(config.name), { depth: null });
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user