Files
Wireguard-tools.js/addons/tools/wginterface.hh
T
Sirherobrine23 16b8561b2b update code
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
2023-10-07 11:26:12 -03:00

335 lines
11 KiB
C++

#pragma once
#include <napi.h>
#include <string>
#include <vector>
#include <map>
#include <wgkeys.hh>
// Get wireguard max name length
unsigned long maxName();
// Get wireguard version
std::string versionDrive();
// On start module call this function
std::string startAddon(const Napi::Env env);
class deleteInterface : public Napi::AsyncWorker {
private:
std::string wgName;
public:
deleteInterface(const Napi::Env env, std::string name): AsyncWorker(env), deletePromise{env}, wgName{name} {}
~deleteInterface() {}
const Napi::Promise::Deferred deletePromise;
void OnError(const Napi::Error &e) override {
Napi::HandleScope scope(Env());
deletePromise.Reject(e.Value());
}
void OnOK() override {
Napi::HandleScope scope(Env());
deletePromise.Resolve(Env().Undefined());
};
// Set platform Execute script
void Execute() override;
};
class listInfo {
public:
std::string tunType, pathSock;
};
class listDevices : public Napi::AsyncWorker {
private:
std::map<std::string, listInfo> deviceNames;
public:
~listDevices() {}
listDevices(const Napi::Env env) : AsyncWorker(env), listDevicesPromise{env} {}
const Napi::Promise::Deferred listDevicesPromise;
void OnError(const Napi::Error& e) override {
Napi::HandleScope scope(Env());
listDevicesPromise.Reject(e.Value());
}
void OnOK() override {
Napi::HandleScope scope(Env());
const Napi::Env env = Env();
const auto deviceArray = Napi::Array::New(env);
for (auto it : deviceNames) {
auto name = it.first; auto infoSrc = it.second;
auto info = Napi::Object::New(env);
info.Set("name", name);
info.Set("from", infoSrc.tunType);
if (infoSrc.pathSock.size() > 0) info.Set("path", infoSrc.pathSock);
deviceArray.Set(deviceArray.Length(), info);
}
listDevicesPromise.Resolve(deviceArray);
};
void Execute() override;
};
class Peer {
public:
// Remove specifies if the peer with this public key should be removed
// from a device's peer list.
bool removeMe;
// PresharedKey is an optional preshared key which may be used as an
// additional layer of security for peer communications.
std::string presharedKey;
// Endpoint is the most recent source address used for communication by
// this Peer.
std::string endpoint;
// AllowedIPs specifies which IPv4 and IPv6 addresses this peer is allowed
// to communicate on.
//
// 0.0.0.0/0 indicates that all IPv4 addresses are allowed, and ::/0
// indicates that all IPv6 addresses are allowed.
std::vector<std::string> allowedIPs;
// PersistentKeepaliveInterval specifies how often an "empty" packet is sent
// to a peer to keep a connection alive.
//
// A value of 0 indicates that persistent keepalives are disabled.
unsigned int keepInterval = 0;
// LastHandshakeTime indicates the most recent time a handshake was performed
// with this peer.
//
// A zero-value time.Time indicates that no handshake has taken place with
// this peer.
long long last_handshake = 0;
// rxBytes indicates the number of bytes received from this peer.
unsigned long long rxBytes = 0;
// txBytes indicates the number of bytes transmitted to this peer.
unsigned long long txBytes = 0;
// ProtocolVersion specifies which version of the WireGuard protocol is used
// for this Peer.
//
// A value of 0 indicates that the most recent protocol version will be used.
int ProtocolVersion = 0;
};
/*
Configure uma interface do Wireguard.
*/
class setConfig : public Napi::AsyncWorker {
private:
// Wireguard interface name (required)
std::string wgName;
// Wireguard private key (required)
std::string privateKey;
// Wireguard interface publicKey <optional>
std::string publicKey;
// Wireguard port listen
unsigned short portListen = 0;
// FirewallMark specifies a device's firewall mark
// else set to 0, the firewall mark will be cleared.
int fwmark = -1;
// Interface address'es
std::vector<std::string> Address;
// Replace peers
bool replacePeers = false;
// Wireguard peers, Map: <publicKey(std::string), Peer>
std::map<std::string, Peer> peersVector;
public:
const Napi::Promise::Deferred setPromise;
void OnOK() override {
Napi::HandleScope scope(Env());
// Callback().Call({ Env().Undefined() });
setPromise.Resolve(Env().Undefined());
};
void OnError(const Napi::Error& e) override {
Napi::HandleScope scope(Env());
// Callback().Call({ e.Value() });
setPromise.Reject(e.Value());
}
~setConfig() {}
setConfig(const Napi::Env env, std::string name, const Napi::Object &config) : AsyncWorker(env), setPromise{env}, wgName{name} {
// Wireguard public key
const auto sppk = config.Get("publicKey");
if (sppk.IsString()) {
publicKey = sppk.ToString().Utf8Value();
if (publicKey.length() != B64_WG_KEY_LENGTH) throw Napi::Error::New(env, "Set valid publicKey");
}
// Private key
const auto sprk = config.Get("privateKey");
if (!(sprk.IsString())) throw Napi::Error::New(env, "privateKey is empty");
privateKey = sprk.ToString().Utf8Value();
if (privateKey.length() != B64_WG_KEY_LENGTH) throw Napi::Error::New(env, (std::string("Set valid privateKey ")).append(std::to_string(privateKey.length())));
// Port to listen Wireguard interface
const auto spor = config.Get("portListen");
if (spor.IsNumber() && (spor.ToNumber().Int32Value() >= 0 && spor.ToNumber().Int32Value() <= 65535)) portListen = spor.ToNumber().Int32Value();
// Firewall mark
const auto sfw = config.Get("fwmark");
if (sfw.IsNumber() && (sfw.ToNumber().Uint32Value() >= 0)) fwmark = sfw.ToNumber().Uint32Value();
else fwmark = -1;
const auto saddr = config.Get("Address");
if (saddr.IsArray()) {
const Napi::Array addrs = saddr.As<Napi::Array>();
for (unsigned int i = 0; i < addrs.Length(); i++) {
if (addrs.Get(i).IsString()) Address.push_back(addrs.Get(i).ToString().Utf8Value());
}
}
// Replace peers
const auto srpee = config.Get("replacePeers");
if (srpee.IsBoolean()) replacePeers = srpee.ToBoolean().Value();
// Peers
const auto speers = config.Get("peers");
if (speers.IsObject()) {
const Napi::Object Peers = speers.ToObject();
const Napi::Array Keys = Peers.GetPropertyNames();
for (unsigned int peerIndex = 0; peerIndex < Keys.Length(); peerIndex++) {
const auto peerPubKey = Keys[peerIndex];
if (peerPubKey.IsString() && Peers.Get(Keys[peerIndex]).IsObject()) {
std::string ppkey = peerPubKey.ToString().Utf8Value();
if (ppkey.length() != B64_WG_KEY_LENGTH) throw Napi::Error::New(env, std::string("Set valid peer publicKey, value: ").append(ppkey));
const Napi::Object peerConfigObject = Peers.Get(Keys[peerIndex]).ToObject();
Peer peerConfig = Peer();
const auto removeMe = peerConfigObject.Get("removeMe");
if (removeMe.IsBoolean() && removeMe.ToBoolean().Value()) peerConfig.removeMe = true;
else {
// Preshared key
const auto pprekey = peerConfigObject.Get("presharedKey");
if (pprekey.IsString()) {
peerConfig.presharedKey = pprekey.ToString().Utf8Value();
if (peerConfig.presharedKey.length() != B64_WG_KEY_LENGTH) throw Napi::Error::New(env, "Set valid peer presharedKey");
}
// Keep interval
const auto pKeepInterval = peerConfigObject.Get("keepInterval");
if (pKeepInterval.IsNumber() && (pKeepInterval.ToNumber().Int32Value() > 0 && pKeepInterval.ToNumber().Int32Value() <= 65535)) peerConfig.keepInterval = pKeepInterval.ToNumber().Int32Value();
// Peer endpoint
const auto pEndpoint = peerConfigObject.Get("endpoint");
if (pEndpoint.IsString()) peerConfig.endpoint = pEndpoint.ToString().Utf8Value();
// Allowed ip's array
const auto pAllowedIPs = peerConfigObject.Get("allowedIPs");
if (pAllowedIPs.IsArray()) {
const auto AllowedIps = pAllowedIPs.As<Napi::Array>();
for (uint32_t allIndex = 0; allIndex < AllowedIps.Length(); allIndex++) {
if (AllowedIps.Get(allIndex).IsString()) peerConfig.allowedIPs.push_back(AllowedIps.Get(allIndex).ToString().Utf8Value());
}
}
}
// Insert peer
peersVector[ppkey] = peerConfig;
}
}
}
}
// Set platform Execute script
void Execute() override;
};
class getConfig : public Napi::AsyncWorker {
private:
// Wireguard interface name (required)
std::string wgName;
// Wireguard private key (required)
std::string privateKey;
// Wireguard interface publicKey <optional>
std::string publicKey;
// Wireguard port listen
uint32_t portListen;
// FirewallMark specifies a device's firewall mark
// else set to 0, the firewall mark will be cleared.
int fwmark = -1;
// Interface address'es
std::vector<std::string> Address;
/*
Wireguard peers
Map: <publicKey, Peer>
*/
std::map<std::string, Peer> peersVector;
public:
~getConfig() {}
getConfig(const Napi::Env env, std::string name): AsyncWorker(env), getPromise{env}, wgName{name} {}
const Napi::Promise::Deferred getPromise;
void OnError(const Napi::Error& e) override {
Napi::HandleScope scope(Env());
getPromise.Reject(e.Value());
}
void OnOK() override {
Napi::HandleScope scope(Env());
const Napi::Env env = Env();
const auto config = Napi::Object::New(env);
if (privateKey.length() == B64_WG_KEY_LENGTH) config.Set("privateKey", privateKey);
if (publicKey.length() == B64_WG_KEY_LENGTH) config.Set("publicKey", publicKey);
if (portListen >= 0 && portListen <= 65535) config.Set("portListen", portListen);
if (fwmark >= 0) config.Set("fwmark", fwmark);
if (Address.size() > 0) {
const auto Addrs = Napi::Array::New(env);
for (auto &addr : Address) Addrs.Set(Addrs.Length(), addr);
config.Set("Address", Addrs);
}
// Peer object
const auto PeersObject = Napi::Object::New(env);
for (auto &peer : peersVector) {
const auto PeerObject = Napi::Object::New(env);
const std::string peerPubKey = peer.first;
auto peerConfig = peer.second;
if (peerConfig.presharedKey.length() == B64_WG_KEY_LENGTH) PeerObject.Set("presharedKey", peerConfig.presharedKey);
if (peerConfig.keepInterval > 0 && peerConfig.keepInterval <= 65535) PeerObject.Set("keepInterval", peerConfig.keepInterval);
if (peerConfig.endpoint.length() > 0) PeerObject.Set("endpoint", peerConfig.endpoint);
if (peerConfig.last_handshake >= 0) PeerObject.Set("lastHandshake", Napi::Date::New(env, peerConfig.last_handshake));
// if (peerConfig.last_handshake >= 0) PeerObject.Set("lastHandshake", peerConfig.last_handshake);
if (peerConfig.rxBytes >= 0) PeerObject.Set("rxBytes", peerConfig.rxBytes);
if (peerConfig.txBytes >= 0) PeerObject.Set("txBytes", peerConfig.txBytes);
if (peerConfig.allowedIPs.size() > 0) {
const auto allowedIPs = Napi::Array::New(env);
for (auto &ip : peerConfig.allowedIPs) allowedIPs.Set(allowedIPs.Length(), ip);
PeerObject.Set("allowedIPs", allowedIPs);
}
PeersObject.Set(peerPubKey, PeerObject);
}
config.Set("peers", PeersObject);
// Resolve config json
getPromise.Resolve(config);
};
// Set platform Execute script
void Execute() override;
};