Skip to content

Commit

Permalink
init async config set in addon
Browse files Browse the repository at this point in the history
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
  • Loading branch information
Sirherobrine23 committed Aug 27, 2023
1 parent 65d0716 commit 7255ed3
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 2 deletions.
1 change: 0 additions & 1 deletion .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"includePath": [
"${env:appdata}/../Local/node-gyp/Cache/18.17.0/include/node",
"${workspaceFolder}/node_modules/node-addon-api",
"${workspaceFolder}/addons/tools/wgtool/wincompat/include",
"${workspaceFolder}/addons/**",
"${workspaceFolder}/addons"
]
Expand Down
5 changes: 5 additions & 0 deletions addons/tools/wginterface-dummy.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <napi.h>
#include <wginterface.hh>

#ifdef _WIN32
#define IFNAMSIZ 64
Expand Down Expand Up @@ -27,4 +28,8 @@ Napi::Value parseWgDeviceSync(const Napi::CallbackInfo& info) {
const Napi::Env env = info.Env();
Napi::Error::New(env, "Use userpace implementation, kernel only on linux!").ThrowAsJavaScriptException();
return env.Undefined();
}

void setConfig::Execute() {
SetError("Use userpace implementation, kernel only on linux!");
}
4 changes: 4 additions & 0 deletions addons/tools/wginterface-linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ Napi::Value mountAllowedIps(wg_peer *peerStruct, Napi::Env env, const Napi::Arra
return env.Undefined();
}

void setConfig::Execute() {
SetError("Not implemented in Linux");
}

Napi::Value setupInterfaceSync(const Napi::CallbackInfo& info) {
const Napi::Env env = info.Env();
const Napi::String interfaceName = info[0].As<Napi::String>();
Expand Down
33 changes: 33 additions & 0 deletions addons/tools/wginterface.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
#include <napi.h>
#include "wginterface.hh"

/** Wireguard function to exec async set config */
Napi::Value setConfigAsync(const Napi::CallbackInfo &info) {
const Napi::Env env = info.Env();
const auto wgName = info[0];
const auto wgConfig = info[1];
const auto callback = info[2];
if (!(wgName.IsString())) {
Napi::Error::New(env, "Require wireguard interface name").ThrowAsJavaScriptException();
return env.Undefined();
} else if (wgName.ToString().Utf8Value().length() > maxName()) {
Napi::Error::New(env, "interface name is so long").ThrowAsJavaScriptException();
return env.Undefined();
} else if (!(wgConfig.IsObject())) {
Napi::Error::New(env, "Require wireguard config object").ThrowAsJavaScriptException();
return env.Undefined();
} else if (!(callback.IsFunction())) {
Napi::Error::New(env, "Require callback").ThrowAsJavaScriptException();
return env.Undefined();
}

try {
const auto ssconfig = new setConfig(env, callback.As<Napi::Function>(), wgName.ToString().Utf8Value(), wgConfig.ToObject());
ssconfig->Queue();
} catch (const Napi::Error &err) {
err.ThrowAsJavaScriptException();
}
return env.Undefined();
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
const Napi::Object constants = Napi::Object::New(env);
constants.Set("MAX_NAME_LENGTH", maxName());

// Constants
exports.Set("constants", constants);

// async function
exports.Set("setConfigAsync", Napi::Function::New(env, setConfigAsync));

// Sync function lock loop
exports.Set("listDevicesSync", Napi::Function::New(env, listDevicesSync));
exports.Set("setupInterfaceSync", Napi::Function::New(env, setupInterfaceSync));
exports.Set("parseWgDeviceSync", Napi::Function::New(env, parseWgDeviceSync));
Expand Down
127 changes: 126 additions & 1 deletion addons/tools/wginterface.hh
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once
#include <napi.h>
#include <string>
#include <vector>
#include <map>

int maxName();

Expand All @@ -16,4 +19,126 @@ Napi::Value parseWgDeviceSync(const Napi::CallbackInfo& info);
/*
Configure uma interface do Wireguard.
*/
Napi::Value setupInterfaceSync(const Napi::CallbackInfo& info);
Napi::Value setupInterfaceSync(const Napi::CallbackInfo& info);

class Peer {
public:
std::string presharedKey;
std::string endpoint;
std::vector<std::string> allowedIPs;
uint32_t keepInterval;
bool removeMe;
};

// Parse config to wireguard interface
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
uint32_t portListen;

// Wiki
uint32_t fwmark;

// Interface address'es
std::vector<std::string> Address;

// Replace peers
bool replacePeers;

/*
Wireguard peers
Map: <publicKey, Peer>
*/
std::map<std::string, Peer> peersVector;
public:
~setConfig() {}
setConfig(const Napi::Env env, const Napi::Function &callback, std::string &name, const Napi::Object &config) : AsyncWorker(callback), wgName(name) {
// Wireguard public key
const auto sppk = config.Get("publicKey");
if (sppk.IsString()) publicKey = sppk.ToString().Utf8Value();

// Private key
const auto sprk = config.Get("privateKey");
if (!(sprk.IsString())) throw Napi::Error::New(env, "privateKey is empty");
privateKey = sprk.ToString().Utf8Value();

// Port to listen Wireguard interface
const auto spor = config.Get("portListen");
if (spor.IsNumber() && (spor.ToNumber().Int32Value() > 0)) portListen = spor.ToNumber().Int32Value();

//\?
const auto sfw = config.Get("fwmark");
if (sfw.IsNumber() && (sfw.ToNumber().Uint32Value() >= 0)) fwmark = sfw.ToNumber().Uint32Value();

// 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();
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();

// Keep interval
const auto pKeepInterval = peerConfigObject.Get("keepInterval");
if (pKeepInterval.IsNumber() && (pKeepInterval.ToNumber().Int32Value() > 0)) 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()) {
std::string ip = AllowedIps.Get(allIndex).ToString().Utf8Value();
peerConfig.allowedIPs.insert(peerConfig.allowedIPs.begin() + 1, ip);
}
}
}
}

// Insert peer
peersVector[ppkey] = peerConfig;
}
}
}
}

// Set platform Execute script
void Execute() override;

void OnOK() override {
Napi::HandleScope scope(Env());
Callback().Call({ Env().Null() });
};
void OnError(const Napi::Error& e) override {
Napi::HandleScope scope(Env());
Callback().Call({ e.Value() });
}
};
3 changes: 3 additions & 0 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
},
{
"target_name": "wginterface",
"include_dirs": [
"addons/tools"
],
"sources": [
"addons/tools/wginterface.cpp"
],
Expand Down

0 comments on commit 7255ed3

Please sign in to comment.