Big code refactoring #10
@ -1,27 +0,0 @@
|
|||||||
#include "wginterface.hh"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
std::string getWireguardVersion() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string driveLoad(std::map<std::string, std::string> load) {}
|
|
||||||
|
|
||||||
void IpManeger::SetInInterface(std::string interfaceName) {
|
|
||||||
throw std::string("Use userspace module");
|
|
||||||
}
|
|
||||||
void IpManeger::GetInInterface(std::string interfaceName) {
|
|
||||||
throw std::string("Use userspace module");
|
|
||||||
}
|
|
||||||
|
|
||||||
void WireguardConfig::setWireguardConfig() {
|
|
||||||
throw std::string("Use userspace module");
|
|
||||||
}
|
|
||||||
void WireguardConfig::getWireguardConfig() {
|
|
||||||
throw std::string("Use userspace module");
|
|
||||||
}
|
|
||||||
|
|
||||||
void WireguardDevices::deleteInterface(std::string wgName) {
|
|
||||||
throw std::string("Use userspace module");
|
|
||||||
}
|
|
||||||
void WireguardDevices::getInterfaces() {}
|
|
@ -263,6 +263,14 @@ void wgKeys::generatePublic(wg_key public_key, const wg_key private_key) {
|
|||||||
memzero_explicit(f, sizeof(f));
|
memzero_explicit(f, sizeof(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string wgKeys::generatePublic(const std::string private_key) {
|
||||||
|
wg_key public_key;
|
||||||
|
wg_key private_key_;
|
||||||
|
stringToKey(private_key_, private_key);
|
||||||
|
generatePublic(public_key, private_key_);
|
||||||
|
return toString(public_key);
|
||||||
|
}
|
||||||
|
|
||||||
bool key_is_zero(const uint8_t key[32]) {
|
bool key_is_zero(const uint8_t key[32]) {
|
||||||
volatile uint8_t acc = 0;
|
volatile uint8_t acc = 0;
|
||||||
|
|
||||||
@ -316,3 +324,18 @@ std::string wgKeys::toString(const wg_key key) {
|
|||||||
|
|
||||||
return std::string(base64);
|
return std::string(base64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string wgKeys::toHex(const std::string keyBase64) {
|
||||||
|
wg_key key;
|
||||||
|
wgKeys::stringToKey(key, keyBase64);
|
||||||
|
char hex[65];
|
||||||
|
for (int i = 0; i < 32; ++i) sprintf(hex + i * 2, "%02x", key[i]);
|
||||||
|
hex[64] = '\0';
|
||||||
|
return std::string(hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string wgKeys::HextoBase64(const std::string keyHex) {
|
||||||
|
wg_key key;
|
||||||
|
for (int i = 0; i < 32; ++i) sscanf(keyHex.c_str() + i * 2, "%02x", &key[i]);
|
||||||
|
return wgKeys::toString(key);
|
||||||
|
}
|
@ -3,29 +3,35 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
const int WG_KEY_LENGTH = 32, B64_WG_KEY_LENGTH = ((WG_KEY_LENGTH + 2) / 3) * 4;
|
const int WG_KEY_LENGTH = 32, B64_WG_KEY_LENGTH = ((WG_KEY_LENGTH + 2) / 3) * 4;
|
||||||
const int wgKeyLength = 32, Base64WgKeyLength = ((wgKeyLength + 2) / 3) * 4;
|
const int wgKeyLength = 32, Base64WgKeyLength = ((wgKeyLength + 2) / 3) * 4, HexWgKeyLength = wgKeyLength * 2;
|
||||||
|
|
||||||
typedef unsigned char wg_key[WG_KEY_LENGTH];
|
typedef unsigned char wg_key[wgKeyLength];
|
||||||
typedef char wg_key_b64_string[B64_WG_KEY_LENGTH + 1];
|
typedef char wg_key_b64_string[Base64WgKeyLength + 1];
|
||||||
typedef long long fe[16];
|
typedef long long fe[16];
|
||||||
|
|
||||||
namespace wgKeys {
|
namespace wgKeys {
|
||||||
/* Convert wg_key to std::string */
|
// Convert wg_key to std::string in base64
|
||||||
std::string toString(const wg_key key);
|
std::string toString(const wg_key key);
|
||||||
|
|
||||||
/* base64 to wg_key */
|
// Convert base64 to hex key
|
||||||
|
std::string toHex(const std::string keyBase64);
|
||||||
|
|
||||||
|
// Convert hex to base64
|
||||||
|
std::string HextoBase64(const std::string keyHex);
|
||||||
|
|
||||||
|
// Convert base64 to wg_key
|
||||||
void stringToKey(wg_key key, std::string keyBase64);
|
void stringToKey(wg_key key, std::string keyBase64);
|
||||||
|
|
||||||
// bool key_is_zero(wg_key key);
|
// Generate preshared key
|
||||||
|
|
||||||
/* Generate preshared key */
|
|
||||||
void generatePreshared(wg_key key);
|
void generatePreshared(wg_key key);
|
||||||
|
|
||||||
/* Generate private key (based on generatePreshared) */
|
// Generate private key
|
||||||
void generatePrivate(wg_key private_key);
|
void generatePrivate(wg_key private_key);
|
||||||
|
|
||||||
/* Get public key from private key */
|
// Get public key from private key
|
||||||
void generatePublic(wg_key public_key, const wg_key private_key);
|
void generatePublic(wg_key public_key, const wg_key private_key);
|
||||||
|
|
||||||
|
std::string generatePublic(const std::string private_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -17,9 +17,8 @@ Napi::Object StartAddon(const Napi::Env env, const Napi::Object exports) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const Napi::Object Constants = Napi::Object::New(env), Userspace = Napi::Object::New(env);
|
const Napi::Object Constants = Napi::Object::New(env);
|
||||||
if (getWireguardVersion().length() > 0) Constants.Set("driveVersion", getWireguardVersion());
|
if (getWireguardVersion().length() > 0) Constants.Set("driveVersion", getWireguardVersion());
|
||||||
Userspace.Set("driveVersion", WireguardUserspace::getWireguardVersion());
|
|
||||||
|
|
||||||
exports.Set("deleteInterface", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
exports.Set("deleteInterface", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||||
const Napi::Env env = info.Env();
|
const Napi::Env env = info.Env();
|
||||||
@ -78,68 +77,7 @@ Napi::Object StartAddon(const Napi::Env env, const Napi::Object exports) {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Userspace.Set("createTunel", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
|
||||||
const Napi::Env env = info.Env();
|
|
||||||
if (!(info[0].IsString())) {
|
|
||||||
Napi::Error::New(env, "Set interface name").ThrowAsJavaScriptException();
|
|
||||||
return env.Undefined();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
auto *worker = new WgUserspace::CreateWgTunnel(env, info[0].ToString());
|
|
||||||
worker->Queue();
|
|
||||||
return worker->NodePromise.Promise();
|
|
||||||
} catch (std::string &err) {
|
|
||||||
Napi::Error::New(env, err).ThrowAsJavaScriptException();
|
|
||||||
return env.Undefined();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
Userspace.Set("deleteTunel", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
|
||||||
const Napi::Env env = info.Env();
|
|
||||||
if (!(info[0].IsString())) {
|
|
||||||
Napi::Error::New(env, "Set interface name").ThrowAsJavaScriptException();
|
|
||||||
return env.Undefined();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
auto *worker = new WgUserspace::DeleteWgTunnel(env, info[0].ToString());
|
|
||||||
worker->Queue();
|
|
||||||
return worker->NodePromise.Promise();
|
|
||||||
} catch (std::string &err) {
|
|
||||||
Napi::Error::New(env, err).ThrowAsJavaScriptException();
|
|
||||||
return env.Undefined();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
Userspace.Set("checkTunel", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
|
||||||
const Napi::Env env = info.Env();
|
|
||||||
if (!(info[0].IsString())) {
|
|
||||||
Napi::Error::New(env, "Set interface name").ThrowAsJavaScriptException();
|
|
||||||
return env.Undefined();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
auto *worker = new WgUserspace::CheckWgTunnel(env, info[0].ToString());
|
|
||||||
worker->Queue();
|
|
||||||
return worker->NodePromise.Promise();
|
|
||||||
} catch (std::string &err) {
|
|
||||||
Napi::Error::New(env, err).ThrowAsJavaScriptException();
|
|
||||||
return env.Undefined();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
Userspace.Set("listTunels", Napi::Function::New(env, [](const Napi::CallbackInfo &info) -> Napi::Value {
|
|
||||||
const Napi::Env env = info.Env();
|
|
||||||
try {
|
|
||||||
auto *worker = new WgUserspace::ListWgTunnels(env);
|
|
||||||
worker->Queue();
|
|
||||||
return worker->NodePromise.Promise();
|
|
||||||
} catch (std::string &err) {
|
|
||||||
Napi::Error::New(env, err).ThrowAsJavaScriptException();
|
|
||||||
return env.Undefined();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
exports.Set("constants", Constants);
|
exports.Set("constants", Constants);
|
||||||
exports.Set("userspace", Userspace);
|
|
||||||
return exports;
|
return exports;
|
||||||
}
|
}
|
||||||
NODE_API_MODULE(addon, StartAddon);
|
NODE_API_MODULE(addon, StartAddon);
|
||||||
|
@ -18,6 +18,16 @@ import (
|
|||||||
|
|
||||||
func main() {}
|
func main() {}
|
||||||
|
|
||||||
|
// End process function callbacks
|
||||||
|
var TunsEndProcess = make(map[string]func())
|
||||||
|
|
||||||
|
//export callEndProcess
|
||||||
|
func callEndProcess() {
|
||||||
|
for _, f := range TunsEndProcess {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//export wgVersion
|
//export wgVersion
|
||||||
func wgVersion() *C.char {
|
func wgVersion() *C.char {
|
||||||
info, ok := debug.ReadBuildInfo()
|
info, ok := debug.ReadBuildInfo()
|
||||||
@ -81,7 +91,10 @@ const levelLog = device.LogLevelVerbose
|
|||||||
func createTun(_tunName *C.char) *C.char {
|
func createTun(_tunName *C.char) *C.char {
|
||||||
interfaceName := C.GoString(_tunName)
|
interfaceName := C.GoString(_tunName)
|
||||||
if existTun(interfaceName) {
|
if existTun(interfaceName) {
|
||||||
return C.CString("Tun already exists")
|
errStr := C.GoString(deleteTun(_tunName))
|
||||||
|
if errStr != "" {
|
||||||
|
return C.CString(errStr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
logger := device.NewLogger(levelLog, fmt.Sprintf("(%s) ", interfaceName))
|
logger := device.NewLogger(levelLog, fmt.Sprintf("(%s) ", interfaceName))
|
||||||
|
|
||||||
@ -127,8 +140,11 @@ func createTun(_tunName *C.char) *C.char {
|
|||||||
if uapiListened[:1] == "/" {
|
if uapiListened[:1] == "/" {
|
||||||
os.Remove(uapiListened)
|
os.Remove(uapiListened)
|
||||||
}
|
}
|
||||||
|
delete(TunsEndProcess, uapiListened)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TunsEndProcess[uapiListened] = clean
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
conn, err := uapi.Accept()
|
conn, err := uapi.Accept()
|
||||||
@ -149,7 +165,13 @@ func createTun(_tunName *C.char) *C.char {
|
|||||||
clean()
|
clean()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
logger.Verbosef("End start process")
|
// Wait for device listener socket to be ready
|
||||||
|
for {
|
||||||
|
_, err := os.Stat(uapiListened)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
return C.CString(strings.Join(([]string{"/", uapiListened}), ""))
|
return C.CString(strings.Join(([]string{"/", uapiListened}), ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
50
addon/userspace/ipc.cpp
Normal file
50
addon/userspace/ipc.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
FILE *interfaceFile(const char *iface) {
|
||||||
|
struct stat sbuf;
|
||||||
|
struct sockaddr_un addr = { .sun_family = AF_UNIX };
|
||||||
|
int fd = -1, ret;
|
||||||
|
FILE *f = NULL;
|
||||||
|
|
||||||
|
errno = EINVAL;
|
||||||
|
if (strchr(iface, '/'))
|
||||||
|
goto out;
|
||||||
|
ret = stat(addr.sun_path, &sbuf);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
errno = EBADF;
|
||||||
|
if (!S_ISSOCK(sbuf.st_mode))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno == ECONNREFUSED) /* If the process is gone, we try to clean up the socket. */
|
||||||
|
unlink(addr.sun_path);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
f = fdopen(fd, "r+");
|
||||||
|
if (f)
|
||||||
|
errno = 0;
|
||||||
|
out:
|
||||||
|
ret = -errno;
|
||||||
|
if (ret) {
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
errno = -ret;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
@ -10,6 +10,10 @@ std::string WireguardUserspace::getWireguardVersion() {
|
|||||||
return wgVersion();
|
return wgVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WireguardUserspace::closeAllWireguardTunnels() {
|
||||||
|
callEndProcess();
|
||||||
|
}
|
||||||
|
|
||||||
// Create tunel and return path to tunel
|
// Create tunel and return path to tunel
|
||||||
std::string WireguardUserspace::createWireguardTunnel(std::string wgName) {
|
std::string WireguardUserspace::createWireguardTunnel(std::string wgName) {
|
||||||
std::string PathError = createTun((char*)wgName.c_str());
|
std::string PathError = createTun((char*)wgName.c_str());
|
||||||
|
155
addon/userspace/wginterface.cpp
Normal file
155
addon/userspace/wginterface.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include "wginterface.hh"
|
||||||
|
#include "userspace/wg-go.h"
|
||||||
|
#include "userspace/ipc.cpp"
|
||||||
|
#include "genKey/wgkeys.hh"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
// Ignore if required to windows
|
||||||
|
std::string driveLoad(std::map<std::string, std::string> load) {}
|
||||||
|
|
||||||
|
std::string getWireguardVersion() {
|
||||||
|
return std::string(wgVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireguardDevices::getInterfaces() {
|
||||||
|
size_t len; char *device_name, *devicesList = listUapis();
|
||||||
|
for (device_name = devicesList, len = 0; (len = strlen(device_name)); device_name += len + 1) this->push_back(std::string(device_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireguardDevices::deleteInterface(std::string wgName) {
|
||||||
|
std::string deleteStatus = deleteTun((char*)wgName.c_str());
|
||||||
|
if (!deleteStatus.empty()) throw deleteStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool char_is_digit(int c) {
|
||||||
|
return (unsigned int)(('0' - 1 - c) & (c - ('9' + 1))) >> (sizeof(c) * 8 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NUM(max) ({ \
|
||||||
|
unsigned long long num; \
|
||||||
|
char *end; \
|
||||||
|
if (!char_is_digit(value[0])) \
|
||||||
|
break; \
|
||||||
|
num = strtoull(value, &end, 10); \
|
||||||
|
if (*end || num > max) \
|
||||||
|
break; \
|
||||||
|
num; \
|
||||||
|
})
|
||||||
|
|
||||||
|
void WireguardConfig::getWireguardConfig() {
|
||||||
|
if (this->name.length() == 0) throw std::string("Set wireguard name!");
|
||||||
|
else if (!(WireguardDevices().exist(this->name))) throw std::string("Wireguard interface not exist");
|
||||||
|
size_t line_buffer_len = 0, line_len;
|
||||||
|
char *key = NULL, *value;
|
||||||
|
int ret = -EPROTO;
|
||||||
|
FILE *f = interfaceFile(WireguardDevices().findSock(this->name).c_str());
|
||||||
|
if (!f) throw std::string("Failed to open interface file");
|
||||||
|
fprintf(f, "get=1\n\n");
|
||||||
|
fflush(f);
|
||||||
|
std::string peerPubKey;
|
||||||
|
bool peer;
|
||||||
|
|
||||||
|
while (getline(&key, &line_buffer_len, f) > 0) {
|
||||||
|
line_len = strlen(key);
|
||||||
|
if (line_len == 1 && key[0] == '\n') return;
|
||||||
|
value = strchr(key, '=');
|
||||||
|
if (!value || line_len == 0 || key[line_len - 1] != '\n') break;
|
||||||
|
*value++ = key[--line_len] = '\0';
|
||||||
|
|
||||||
|
if (this->Peers.size() == 0 && !strcmp(key, "private_key")) {
|
||||||
|
this->privateKey = wgKeys::HextoBase64(value);
|
||||||
|
this->publicKey = wgKeys::generatePublic(this->privateKey);
|
||||||
|
} else if (this->Peers.size() == 0 && !strcmp(key, "listen_port")) {
|
||||||
|
this->portListen = NUM(0xffffU);
|
||||||
|
} else if (this->Peers.size() == 0 && !strcmp(key, "fwmark")) {
|
||||||
|
this->fwmark = NUM(0xffffffffU);
|
||||||
|
} else if (!strcmp(key, "public_key")) {
|
||||||
|
Peer new_peer;
|
||||||
|
peerPubKey = wgKeys::HextoBase64(value);
|
||||||
|
this->Peers[peerPubKey] = new_peer;
|
||||||
|
|
||||||
|
} else if (peer && !strcmp(key, "preshared_key")) {
|
||||||
|
if (strlen(value) == HexWgKeyLength) this->Peers[peerPubKey].presharedKey = wgKeys::HextoBase64(value);
|
||||||
|
} else if (peer && !strcmp(key, "endpoint")) {
|
||||||
|
char *begin, *end;
|
||||||
|
struct addrinfo *resolved;
|
||||||
|
struct addrinfo hints = {
|
||||||
|
.ai_family = AF_UNSPEC,
|
||||||
|
.ai_socktype = SOCK_DGRAM,
|
||||||
|
.ai_protocol = IPPROTO_UDP
|
||||||
|
};
|
||||||
|
if (!strlen(value))
|
||||||
|
break;
|
||||||
|
if (value[0] == '[') {
|
||||||
|
begin = &value[1];
|
||||||
|
end = strchr(value, ']');
|
||||||
|
if (!end)
|
||||||
|
break;
|
||||||
|
*end++ = '\0';
|
||||||
|
if (*end++ != ':' || !*end)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
begin = value;
|
||||||
|
end = strrchr(value, ':');
|
||||||
|
if (!end || !*(end + 1))
|
||||||
|
break;
|
||||||
|
*end++ = '\0';
|
||||||
|
}
|
||||||
|
if (getaddrinfo(begin, end, &hints, &resolved) != 0) {
|
||||||
|
ret = ENETUNREACH;
|
||||||
|
throw std::string("Failed to resolve endpoint");
|
||||||
|
}
|
||||||
|
if ((resolved->ai_family == AF_INET && resolved->ai_addrlen == sizeof(struct sockaddr_in))
|
||||||
|
|| (resolved->ai_family == AF_INET6 && resolved->ai_addrlen == sizeof(struct sockaddr_in6)))
|
||||||
|
this->Peers[peerPubKey].endpoint = value;
|
||||||
|
else {
|
||||||
|
freeaddrinfo(resolved);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
freeaddrinfo(resolved);
|
||||||
|
} else if (peer && !strcmp(key, "persistent_keepalive_interval")) {
|
||||||
|
this->Peers[peerPubKey].keepInterval = NUM(0xffffU);
|
||||||
|
} else if (peer && !strcmp(key, "allowed_ip")) {
|
||||||
|
this->Peers[peerPubKey].allowedIPs.push_back(value);
|
||||||
|
}
|
||||||
|
else if (peer && !strcmp(key, "last_handshake_time_sec")) {}
|
||||||
|
else if (peer && !strcmp(key, "last_handshake_time_nsec"))
|
||||||
|
this->Peers[peerPubKey].lastHandshake = NUM(0x7fffffffffffffffULL);
|
||||||
|
else if (peer && !strcmp(key, "rx_bytes"))
|
||||||
|
this->Peers[peerPubKey].rxBytes = NUM(0xffffffffffffffffULL);
|
||||||
|
else if (peer && !strcmp(key, "tx_bytes"))
|
||||||
|
this->Peers[peerPubKey].txBytes = NUM(0xffffffffffffffffULL);
|
||||||
|
else if (!strcmp(key, "errno"))
|
||||||
|
ret = -NUM(0x7fffffffU);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(key);
|
||||||
|
fclose(f);
|
||||||
|
if (ret < 0) throw std::string("Failed to get wireguard config");
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireguardConfig::setWireguardConfig() {
|
||||||
|
if (this->name.length() == 0) throw std::string("Set wireguard name!");
|
||||||
|
else if (!(WireguardDevices().exist(this->name))) {
|
||||||
|
std::string PathError = createTun((char*)this->name.c_str());
|
||||||
|
if (PathError.rfind("/", 0) != 0) throw PathError;
|
||||||
|
}
|
||||||
|
FILE *f = interfaceFile(WireguardDevices().findSock(this->name).c_str());
|
||||||
|
if (!f) throw std::string("Failed to open interface file");
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpManeger::SetInInterface(std::string interfaceName) {}
|
||||||
|
void IpManeger::GetInInterface(std::string interfaceName) {}
|
72
addon/wg.hh
72
addon/wg.hh
@ -172,76 +172,4 @@ class GetConfig : public WireguardConfig, public Promised {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace WgUserspace {
|
|
||||||
class CreateWgTunnel : public Promised {
|
|
||||||
std::string tunName;
|
|
||||||
public:
|
|
||||||
CreateWgTunnel(const Napi::Env &env, const Napi::String &name): Promised(env), tunName{name.Utf8Value()} {}
|
|
||||||
|
|
||||||
void runOk(std::function<void(Napi::Value)> callback) override {
|
|
||||||
Napi::HandleScope scope(Env());
|
|
||||||
callback(Napi::String::New(Env(), tunName));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Execute() override {
|
|
||||||
try {
|
|
||||||
std::string status = WireguardUserspace::createWireguardTunnel(tunName);
|
|
||||||
if (status.rfind("/", 0) != 0) SetError(status);
|
|
||||||
else tunName = status;
|
|
||||||
} catch (std::string &err) { SetError(err); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DeleteWgTunnel : public Promised {
|
|
||||||
std::string tunName;
|
|
||||||
public:
|
|
||||||
DeleteWgTunnel(const Napi::Env &env, const Napi::String &name): Promised(env), tunName{name.Utf8Value()} {}
|
|
||||||
|
|
||||||
void Execute() override {
|
|
||||||
try {
|
|
||||||
WireguardUserspace::deleteWireguardTunnel(tunName);
|
|
||||||
} catch (std::string &err) { SetError(err); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CheckWgTunnel : public Promised {
|
|
||||||
std::string tunName;
|
|
||||||
bool status;
|
|
||||||
public:
|
|
||||||
CheckWgTunnel(const Napi::Env &env, const Napi::String &name): Promised(env), tunName{name.Utf8Value()} {}
|
|
||||||
|
|
||||||
void Execute() override {
|
|
||||||
try {
|
|
||||||
status = WireguardUserspace::checkIfExistTunnel(tunName);
|
|
||||||
} catch (std::string &err) { SetError(err); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void runOk(std::function<void(Napi::Value)> callback) override {
|
|
||||||
Napi::HandleScope scope(Env());
|
|
||||||
callback(Napi::Boolean::New(Env(), status));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ListWgTunnels : public Promised {
|
|
||||||
public:
|
|
||||||
ListWgTunnels(const Napi::Env &env): Promised(env) {}
|
|
||||||
std::vector<std::string> tuns;
|
|
||||||
|
|
||||||
void Execute() override {
|
|
||||||
try {
|
|
||||||
tuns = WireguardUserspace::listTunnels();
|
|
||||||
if (tuns.size() == 0) SetError("No interfaces found");
|
|
||||||
} catch (std::string &err) { SetError(err); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void runOk(std::function<void(Napi::Value)> callback) override {
|
|
||||||
Napi::HandleScope scope(Env());
|
|
||||||
const Napi::Env env = Env();
|
|
||||||
const Napi::Array interf = Napi::Array::New(env);
|
|
||||||
for (auto &ip : tuns) interf.Set(interf.Length(), ip);
|
|
||||||
callback(interf);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,10 +26,36 @@ class WireguardDevices : public std::vector<std::string> {
|
|||||||
this->getInterfaces();
|
this->getInterfaces();
|
||||||
for (auto wgDev = this->begin(); wgDev != this->end(); ++wgDev) {
|
for (auto wgDev = this->begin(); wgDev != this->end(); ++wgDev) {
|
||||||
if (name == *wgDev) return true;
|
if (name == *wgDev) return true;
|
||||||
|
else if (wgDev->find_last_of(".sock") != std::string::npos) {
|
||||||
|
wgDev->erase(wgDev->find_last_of(".sock"));
|
||||||
|
if (name == *wgDev) return true;
|
||||||
|
if (wgDev->find_last_of("/wg") != std::string::npos) {
|
||||||
|
wgDev->erase(wgDev->find_last_of("/wg"));
|
||||||
|
if (name == *wgDev) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Find sock */
|
||||||
|
std::string findSock(std::string name) {
|
||||||
|
this->getInterfaces();
|
||||||
|
for (auto wgDev = this->begin(); wgDev != this->end(); ++wgDev) {
|
||||||
|
if (name == *wgDev) return *wgDev;
|
||||||
|
else if (wgDev->find_last_of(".sock") != std::string::npos) {
|
||||||
|
wgDev->erase(wgDev->find_last_of(".sock"));
|
||||||
|
if (name == *wgDev) return *wgDev;
|
||||||
|
if (wgDev->find_last_of("/wg") != std::string::npos) {
|
||||||
|
wgDev->erase(wgDev->find_last_of("/wg"));
|
||||||
|
if (name == *wgDev) return *wgDev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string("");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -199,6 +225,9 @@ namespace WireguardUserspace {
|
|||||||
// Get Wireguard-go version
|
// Get Wireguard-go version
|
||||||
std::string getWireguardVersion();
|
std::string getWireguardVersion();
|
||||||
|
|
||||||
|
// Close all wireguard tunels
|
||||||
|
void closeAllWireguardTunnels();
|
||||||
|
|
||||||
// Create tunel and return path to tunel
|
// Create tunel and return path to tunel
|
||||||
std::string createWireguardTunnel(std::string wgName);
|
std::string createWireguardTunnel(std::string wgName);
|
||||||
|
|
||||||
|
@ -8,9 +8,7 @@ includes:
|
|||||||
sources:
|
sources:
|
||||||
- "addon/main.cpp"
|
- "addon/main.cpp"
|
||||||
- "addon/genKey/wgkeys.cpp"
|
- "addon/genKey/wgkeys.cpp"
|
||||||
- "addon/userspace/userspace.cpp"
|
- "addon/userspace/wginterface.cpp"
|
||||||
# Set undefined functions to non supported system
|
|
||||||
- "addon/dummy/wginterface.cpp"
|
|
||||||
prebuild:
|
prebuild:
|
||||||
- shell: bash
|
- shell: bash
|
||||||
cwd: ./addon/userspace/go
|
cwd: ./addon/userspace/go
|
||||||
@ -23,7 +21,7 @@ prebuild:
|
|||||||
target:
|
target:
|
||||||
linux:
|
linux:
|
||||||
sources:
|
sources:
|
||||||
- "!addon/dummy/wginterface.cpp"
|
- "!addon/userspace/wginterface.cpp"
|
||||||
- "addon/linux/wginterface.cpp"
|
- "addon/linux/wginterface.cpp"
|
||||||
- "addon/linux/wireguard.c"
|
- "addon/linux/wireguard.c"
|
||||||
flags:
|
flags:
|
||||||
@ -35,7 +33,7 @@ target:
|
|||||||
- "-fPIC"
|
- "-fPIC"
|
||||||
windows:
|
windows:
|
||||||
sources:
|
sources:
|
||||||
- "!addon/dummy/wginterface.cpp"
|
- "!addon/userspace/wginterface.cpp"
|
||||||
- "addon/win/wginterface.cpp"
|
- "addon/win/wginterface.cpp"
|
||||||
libraries:
|
libraries:
|
||||||
- wbemuuid.lib
|
- wbemuuid.lib
|
||||||
|
Loading…
x
Reference in New Issue
Block a user