Skip to content

Commit a0c5e7e

Browse files
Droping rebory and migrate to cmake-js (#14)
- Migrate to cmake-js - Fix and pretty userspace in go binding - fix typescript code Reviewed-on: https://sirherobrine23.org/Wireguard/Wireguard-tools.js/pulls/14 Co-authored-by: Matheus Sampaio Queiroga <[email protected]> Co-committed-by: Matheus Sampaio Queiroga <[email protected]>
1 parent b26f59e commit a0c5e7e

26 files changed

+564
-847
lines changed

.github/workflows/test.yaml

+4-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
runs-on: ubuntu-latest
1414
strategy:
1515
matrix:
16-
node-version: [ 16.x, 18.x, 20.x, latest ]
16+
node-version: [ 18.x, 20.x, 21.x, latest ]
1717
steps:
1818
- name: Disable sudo PATH replace
1919
run: |
@@ -32,18 +32,13 @@ jobs:
3232
- uses: actions/setup-go@v4
3333
with:
3434
go-version-file: addon/userspace/go/go.mod
35-
go-version: ">=1.22.0"
36-
37-
- name: "Setup zig"
38-
uses: korandoru/setup-zig@v1
39-
with:
40-
zig-version: "master"
35+
go-version: ">=1.22"
4136

4237
- name: Install build dependencies
43-
run: sudo apt update && sudo apt install -y build-essential
38+
run: sudo apt update && sudo apt install -y build-essential cmake
4439

4540
- name: Install node dependencies
4641
run: npm install --no-save --no-audit --no-fund --ignore-scripts
4742

4843
- name: Run tests
49-
run: ./node_modules/.bin/rebory build && sudo node --no-warnings --loader ts-node/esm src/index_test.js
44+
run: npm run build && sudo node --no-warnings --loader ts-node/esm src/index_test.js

.npmignore

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@
22
node_modules/
33
/*.tgz
44

5+
# Builder dir
6+
build/
7+
58
# Typescript
69
src/**/*_test.*
710
src/**/*.ts
811
!src/**/*.d.ts
912

10-
# vscode
13+
# IDEs
1114
.devcontainer/
12-
.vscode/
1315
.vscode-ctags
16+
.vscode/
17+
.zed/
1418

1519
# Github and Git
1620
.github/
1721
.git*
1822

1923
# Project
2024
.vscode-ctags*
21-
*.addrs.json
25+
*.addrs.json

.vscode/settings.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116
"xtr1common": "cpp",
117117
"xtree": "cpp",
118118
"xutility": "cpp",
119-
"fstream": "cpp"
119+
"fstream": "cpp",
120+
"deque": "cpp",
121+
"stack": "cpp"
120122
}
121123
}

.zed/settings.json

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Folder-specific settings
2+
//
3+
// For a full list of overridable settings, and general information on folder-specific settings,
4+
// see the documentation: https://zed.dev/docs/configuring-zed#folder-specific-settings
5+
{
6+
"remove_trailing_whitespace_on_save": true,
7+
"ensure_final_newline_on_save": true,
8+
"formatter": "auto",
9+
"format_on_save": "off",
10+
"tab_size": 2,
11+
"file_scan_exclusions": [
12+
"/*-lock",
13+
"/node_modules",
14+
"/build"
15+
],
16+
"languages": {
17+
"TypeScript": {
18+
"hard_tabs": false
19+
"format_on_save": true,
20+
"code_actions_on_format": {
21+
"source.organizeImports": true,
22+
"source.removeUnusedImports": true
23+
}
24+
},
25+
"JavaScript": {
26+
"hard_tabs": false
27+
"format_on_save": true,
28+
"code_actions_on_format": {
29+
"source.organizeImports": true,
30+
"source.removeUnusedImports": true
31+
}
32+
},
33+
"Go": {
34+
"format_on_save": true
35+
},
36+
"C++": {
37+
"hard_tabs": false
38+
},
39+
"C": {
40+
"hard_tabs": false
41+
}
42+
}
43+
}

CMakeLists.txt

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
cmake_minimum_required(VERSION 3.15)
2+
cmake_policy(SET CMP0091 NEW)
3+
cmake_policy(SET CMP0042 NEW)
4+
5+
project (wg)
6+
7+
add_compile_definitions(NAPI_VERSION=8 NAPI_CPP_EXCEPTIONS)
8+
set(CMAKE_C_STANDARD 17)
9+
set(CMAKE_CXX_STANDARD 17)
10+
11+
execute_process(COMMAND node -p "require('node-addon-api').include"
12+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
13+
OUTPUT_VARIABLE NODE_ADDON_API_DIR
14+
)
15+
string(REPLACE "\n" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
16+
string(REPLACE "\"" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
17+
include_directories(PRIVATE ${NODE_ADDON_API_DIR})
18+
include_directories(${CMAKE_JS_INC})
19+
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon")
20+
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon/genKey")
21+
22+
if(UNIX)
23+
add_definitions(-fpermissive -fexceptions -w -fpermissive -fPIC)
24+
endif()
25+
26+
file(GLOB SOURCE_FILES
27+
"${CMAKE_CURRENT_SOURCE_DIR}/addon/main.cpp"
28+
"${CMAKE_CURRENT_SOURCE_DIR}/addon/genKey/wgkeys.cpp"
29+
)
30+
31+
if(MSVC)
32+
file(GLOB SOURCE_FILES ${SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/addon/win/wginterface.cpp")
33+
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon/win")
34+
add_compile_definitions(_HAS_EXCEPTIONS=1 ONSTARTADDON)
35+
target_link_libraries(${PROJECT_NAME}
36+
"wbemuuid.lib"
37+
"bcrypt.lib"
38+
"crypt32.lib"
39+
"iphlpapi.lib"
40+
"kernel32.lib"
41+
"ntdll.lib"
42+
"ws2_32.lib"
43+
"setupapi.lib"
44+
)
45+
elseif(UNIX AND NOT APPLE OR ANDROID)
46+
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon/linux")
47+
file(GLOB SOURCE_FILES ${SOURCE_FILES}
48+
"${CMAKE_CURRENT_SOURCE_DIR}/addon/linux/wireguard.c"
49+
"${CMAKE_CURRENT_SOURCE_DIR}/addon/linux/wginterface.cpp"
50+
)
51+
else()
52+
message(STATUS "Buiding go Userspace")
53+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.o)
54+
file(REMOVE_RECURSE ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.o)
55+
endif()
56+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.h)
57+
file(REMOVE_RECURSE ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.h)
58+
endif()
59+
set(ENV{CGO_ENABLED} 1)
60+
set(ENV{LDFLAGS} -w)
61+
# Remove CXX and CC envs to CGO
62+
set(ENV{DCXX} ENV{CXX})
63+
set(ENV{DCC} ENV{CC})
64+
set(ENV{CXX})
65+
set(ENV{CC})
66+
execute_process(
67+
COMMAND go build -trimpath -v -o ../wg-go.o -buildmode c-archive .
68+
# COMMAND env
69+
RESULT_VARIABLE GOCODE
70+
OUTPUT_VARIABLE GOBUILDLOG
71+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/go
72+
)
73+
set(ENV{CXX} ENV{DCXX})
74+
set(ENV{CC} ENV{DCC})
75+
if(NOT GOCODE EQUAL "0")
76+
message(FATAL_ERROR "cannot build go userspace code exit ${GOCODE}\n${GOBUILDLOG}")
77+
endif()
78+
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace")
79+
set(USERSPACEOBJ ${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wg-go.o)
80+
file(GLOB SOURCE_FILES ${SOURCE_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/addon/userspace/wginterface.cpp")
81+
endif()
82+
83+
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
84+
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
85+
target_link_libraries(${PROJECT_NAME} ${USERSPACEOBJ} ${CMAKE_JS_LIB})
86+
87+
if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
88+
# Generate node.lib
89+
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
90+
endif()

README.md

+34
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,42 @@
22

33
Manage your Wireguard interfaces directly from Node.js without any wrappers over `wg` or `wg-quick`
44

5+
> [!WARNING]
6+
> Require cmake and tools (GCC/GCC++, clang or Visual Studio) to build this addon
7+
>
8+
> New versions does't include prebuilt binaries
9+
510
```js
11+
import { setConfig, getConfig, key, Config } from "../index.js"
12+
13+
const tunName = process.platform === "darwin" ? "utun10" : "wg3" // Tunnel name, in MacOS/Darwin require start with utun prefix
14+
let currentConfig: Config
15+
try {
16+
currentConfig = await getConfig(tunName) // Check if exists tun
17+
} catch {
18+
// Create new wireguard tun
19+
currentConfig = {
20+
name: tunName,
21+
privateKey: await key.privateKey(),
22+
portListen: 5820,
23+
address: [
24+
"10.66.66.1/24"
25+
],
26+
peers: {}
27+
}
28+
}
29+
30+
// Add new Peer
31+
const peerPrivate = await key.privateKey()
32+
currentConfig.peers[key.publicKey(peerPrivate)] = {
33+
presharedKey: await key.presharedKey(),
34+
allowedIPs: [
35+
"10.66.66.2/24"
36+
]
37+
}
638

39+
// Deploy new Config
40+
await setConfig(currentConfig)
741
```
842

943
## Licences

addon/genKey/wgkeys.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "wgkeys.hh"
22
#include <errno.h>
33
#include <fcntl.h>
4+
#include <iostream>
45
#include <random>
6+
#include <sstream>
57
#include <string.h>
68

79
#ifdef __linux__
@@ -263,7 +265,7 @@ void wgKeys::generatePublic(wg_key public_key, const wg_key private_key) {
263265
memzero_explicit(f, sizeof(f));
264266
}
265267

266-
std::string wgKeys::generatePublic(const std::string private_key) {
268+
std::string wgKeys::generatePublic(const std::string &private_key) {
267269
wg_key public_key;
268270
wg_key private_key_;
269271
stringToKey(private_key_, private_key);
@@ -282,7 +284,7 @@ bool key_is_zero(const uint8_t key[32]) {
282284
}
283285

284286
void wgKeys::stringToKey(wg_key key, std::string keyBase64) {
285-
auto base64 = keyBase64.c_str();
287+
const char* base64 = keyBase64.c_str();
286288
if (keyBase64.length() != B64_WG_KEY_LENGTH ||
287289
base64[B64_WG_KEY_LENGTH - 1] != '=')
288290
throw std::string("invalid key, length: ")
@@ -315,8 +317,7 @@ std::string wgKeys::toString(const wg_key key) {
315317
wg_key_b64_string base64;
316318
unsigned int i;
317319

318-
for (i = 0; i < 32 / 3; ++i)
319-
encode_base64(&base64[i * 4], &key[i * 3]);
320+
for (i = 0; i < 32 / 3; ++i) encode_base64(&base64[i * 4], &key[i * 3]);
320321
const uint8_t tempKey[3] = {key[i * 3 + 0], key[i * 3 + 1], 0};
321322
encode_base64(&base64[i * 4], tempKey);
322323
base64[sizeof(wg_key_b64_string) - 2] = '=';
@@ -325,7 +326,7 @@ std::string wgKeys::toString(const wg_key key) {
325326
return std::string(base64);
326327
}
327328

328-
std::string wgKeys::toHex(const std::string keyBase64) {
329+
std::string wgKeys::toHex(const std::string &keyBase64) {
329330
wg_key key;
330331
wgKeys::stringToKey(key, keyBase64);
331332
char hex[65];
@@ -334,8 +335,11 @@ std::string wgKeys::toHex(const std::string keyBase64) {
334335
return std::string(hex);
335336
}
336337

337-
std::string wgKeys::HextoBase64(const std::string keyHex) {
338+
std::string wgKeys::HextoBase64(const std::string &s_hex) {
338339
wg_key key;
339-
for (int i = 0; i < 32; ++i) sscanf(keyHex.c_str() + i * 2, "%02x", &key[i]);
340+
for(unsigned i = 0, uchr ; i < s_hex.length() ; i += 2) {
341+
sscanf( s_hex.c_str()+ i, "%2x", &uchr); // conversion
342+
key[i/2] = uchr; // save as char
343+
}
340344
return wgKeys::toString(key);
341345
}

addon/genKey/wgkeys.hh

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ namespace wgKeys {
1414
std::string toString(const wg_key key);
1515

1616
// Convert base64 to hex key
17-
std::string toHex(const std::string keyBase64);
17+
std::string toHex(const std::string &keyBase64);
1818

1919
// Convert hex to base64
20-
std::string HextoBase64(const std::string keyHex);
20+
std::string HextoBase64(const std::string &keyHex);
2121

2222
// Convert base64 to wg_key
2323
void stringToKey(wg_key key, std::string keyBase64);
@@ -31,7 +31,7 @@ namespace wgKeys {
3131
// Get public key from private key
3232
void generatePublic(wg_key public_key, const wg_key private_key);
3333

34-
std::string generatePublic(const std::string private_key);
34+
std::string generatePublic(const std::string &private_key);
3535
}
3636

3737
#endif

addon/linux/wginterface.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ std::string getWireguardVersion() {
3030
#endif
3131

3232
std::string version = "Unknown";
33-
33+
3434
// /sys/module/wireguard/version - for kernel module
3535
if (std::filesystem::exists("/sys/module/wireguard/version")) {
3636
std::ifstream file("/sys/module/wireguard/version");
@@ -100,9 +100,9 @@ void WireguardConfig::getWireguardConfig() {
100100
for ((peer) = (devConfig)->first_peer; (peer); (peer) = (peer)->next_peer) {
101101
auto PeerConfig = Peer();
102102
if (peer->flags & WGPEER_HAS_PRESHARED_KEY) PeerConfig.presharedKey = wgKeys::toString(peer->preshared_key);
103-
if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL) PeerConfig.keepInterval = peer->persistent_keepalive_interval;
104103
if (peer->endpoint.addr.sa_family == AF_INET||peer->endpoint.addr.sa_family == AF_INET6) PeerConfig.endpoint = HostAdresses(true, &peer->endpoint.addr);
105104

105+
PeerConfig.keepInterval = peer->persistent_keepalive_interval;
106106
PeerConfig.lastHandshake = peer->last_handshake_time.tv_sec*1000;
107107
PeerConfig.rxBytes = peer->rx_bytes;
108108
PeerConfig.txBytes = peer->tx_bytes;

addon/main.cpp

-12
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,6 @@ Napi::Object StartAddon(const Napi::Env env, const Napi::Object exports) {
3636
}
3737
}));
3838

39-
exports.Set("listDevices", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
40-
const Napi::Env env = info.Env();
41-
try {
42-
ListDevices *worker = new ListDevices(env);
43-
worker->Queue();
44-
return worker->NodePromise.Promise();
45-
} catch (std::string &err) {
46-
Napi::Error::New(env, err).ThrowAsJavaScriptException();
47-
return env.Undefined();
48-
}
49-
}));
50-
5139
exports.Set("setConfig", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
5240
const Napi::Env env = info.Env();
5341
if (!(info[0].IsObject())) Napi::Error::New(env, "Set wireguard config!").ThrowAsJavaScriptException();

addon/userspace/go/go.sum

-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
22
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
3-
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
4-
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
53
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
64
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
7-
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
8-
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
95
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
106
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
11-
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
12-
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
137
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
148
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
159
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=

0 commit comments

Comments
 (0)