Big code refactoring #10
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -115,6 +115,7 @@
|
|||||||
"xmemory": "cpp",
|
"xmemory": "cpp",
|
||||||
"xtr1common": "cpp",
|
"xtr1common": "cpp",
|
||||||
"xtree": "cpp",
|
"xtree": "cpp",
|
||||||
"xutility": "cpp"
|
"xutility": "cpp",
|
||||||
|
"fstream": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,18 +5,18 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"golang.zx2c4.com/wireguard/conn"
|
"golang.zx2c4.com/wireguard/conn"
|
||||||
"golang.zx2c4.com/wireguard/device"
|
"golang.zx2c4.com/wireguard/device"
|
||||||
"golang.zx2c4.com/wireguard/ipc"
|
"golang.zx2c4.com/wireguard/ipc"
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
|
|
||||||
_ "unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {}
|
const levelLog = device.LogLevelError
|
||||||
|
|
||||||
// End process function callbacks
|
// End process function callbacks
|
||||||
var TunsEndProcess = make(map[string]func())
|
var TunsEndProcess = make(map[string]func())
|
||||||
@ -28,6 +28,18 @@ func callEndProcess() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
func init() {
|
||||||
|
c := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
|
go func() {
|
||||||
|
<-c
|
||||||
|
callEndProcess()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get wireguard-go version
|
||||||
|
//
|
||||||
//export wgVersion
|
//export wgVersion
|
||||||
func wgVersion() *C.char {
|
func wgVersion() *C.char {
|
||||||
info, ok := debug.ReadBuildInfo()
|
info, ok := debug.ReadBuildInfo()
|
||||||
@ -42,6 +54,8 @@ func wgVersion() *C.char {
|
|||||||
return C.CString("unknown")
|
return C.CString("unknown")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if tunnel exist
|
||||||
|
//
|
||||||
//export existTun
|
//export existTun
|
||||||
func existTun(tunName string) bool {
|
func existTun(tunName string) bool {
|
||||||
Files, err := os.ReadDir(socketDirectory)
|
Files, err := os.ReadDir(socketDirectory)
|
||||||
@ -61,6 +75,8 @@ func existTun(tunName string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete wireguard tunnel if exist
|
||||||
|
//
|
||||||
//export deleteTun
|
//export deleteTun
|
||||||
func deleteTun(_tunName *C.char) *C.char {
|
func deleteTun(_tunName *C.char) *C.char {
|
||||||
tunName := C.GoString(_tunName)
|
tunName := C.GoString(_tunName)
|
||||||
@ -85,8 +101,8 @@ func deleteTun(_tunName *C.char) *C.char {
|
|||||||
return C.CString("Tun does not exist")
|
return C.CString("Tun does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
const levelLog = device.LogLevelVerbose
|
// Create wireguard tunnel
|
||||||
|
//
|
||||||
//export createTun
|
//export createTun
|
||||||
func createTun(_tunName *C.char) *C.char {
|
func createTun(_tunName *C.char) *C.char {
|
||||||
interfaceName := C.GoString(_tunName)
|
interfaceName := C.GoString(_tunName)
|
||||||
@ -172,10 +188,12 @@ func createTun(_tunName *C.char) *C.char {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return C.CString(strings.Join(([]string{"/", uapiListened}), ""))
|
return C.CString("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List wireguard-go UAPI's sockets
|
||||||
// first\0second\0third\0forth\0last\0\0
|
// first\0second\0third\0forth\0last\0\0
|
||||||
|
//
|
||||||
//export listUapis
|
//export listUapis
|
||||||
func listUapis() *C.char {
|
func listUapis() *C.char {
|
||||||
Files, err := os.ReadDir(socketDirectory)
|
Files, err := os.ReadDir(socketDirectory)
|
||||||
@ -190,4 +208,4 @@ func listUapis() *C.char {
|
|||||||
uapis = append(uapis, strings.Join(([]string{socketDirectory, file.Name()}), "/"))
|
uapis = append(uapis, strings.Join(([]string{socketDirectory, file.Name()}), "/"))
|
||||||
}
|
}
|
||||||
return C.CString(strings.Join(uapis, "\x00") + "\x00")
|
return C.CString(strings.Join(uapis, "\x00") + "\x00")
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
//go:build linux || darwin || freebsd || openbsd
|
//go:build linux || darwin || freebsd || openbsd
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
_ "unsafe"
|
|
||||||
|
|
||||||
_ "golang.zx2c4.com/wireguard/ipc"
|
_ "golang.zx2c4.com/wireguard/ipc"
|
||||||
|
_ "unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname socketDirectory golang.xz2c4.com/wireguard/ipc.socketDirectory
|
//go:linkname socketDirectory golang.xz2c4.com/wireguard/ipc.socketDirectory
|
||||||
var socketDirectory = "/var/run/wireguard"
|
var socketDirectory = "/var/run/wireguard"
|
||||||
|
|
||||||
//go:linkname sockPath golang.xz2c4.com/wireguard/ipc.sockPath
|
|
||||||
func sockPath(iface string) string {
|
|
||||||
return fmt.Sprintf("%s/%s.sock", socketDirectory, iface)
|
|
||||||
}
|
|
5
addon/userspace/go/main_windows.go
Normal file
5
addon/userspace/go/main_windows.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
var socketDirectory = `\\.\pipe\ProtectedPrefix\Administrators\WireGuard`
|
@ -8,43 +8,47 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
FILE *interfaceFile(const char *iface) {
|
FILE *interfaceFile(std::string sockPath) {
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
struct sockaddr_un addr = { .sun_family = AF_UNIX };
|
struct sockaddr_un addr = { .sun_family = AF_UNIX };
|
||||||
int fd = -1, ret;
|
int fd = -1, ret;
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
|
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
if (strchr(iface, '/'))
|
ret = snprintf(addr.sun_path, sizeof(addr.sun_path), sockPath.c_str());
|
||||||
goto out;
|
if (ret < 0)
|
||||||
ret = stat(addr.sun_path, &sbuf);
|
goto out;
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
errno = EBADF;
|
|
||||||
if (!S_ISSOCK(sbuf.st_mode))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
ret = stat(addr.sun_path, &sbuf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
|
errno = EBADF;
|
||||||
if (ret < 0) {
|
if (!S_ISSOCK(sbuf.st_mode))
|
||||||
if (errno == ECONNREFUSED) /* If the process is gone, we try to clean up the socket. */
|
goto out;
|
||||||
unlink(addr.sun_path);
|
|
||||||
goto out;
|
ret = fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
}
|
if (ret < 0)
|
||||||
f = fdopen(fd, "r+");
|
goto out;
|
||||||
if (f)
|
|
||||||
errno = 0;
|
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:
|
out:
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
@ -1,47 +0,0 @@
|
|||||||
#include "userspace/wg-go.h"
|
|
||||||
#include "wginterface.hh"
|
|
||||||
#include <iostream>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Get Wireguard-go version
|
|
||||||
std::string WireguardUserspace::getWireguardVersion() {
|
|
||||||
return wgVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WireguardUserspace::closeAllWireguardTunnels() {
|
|
||||||
callEndProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create tunel and return path to tunel
|
|
||||||
std::string WireguardUserspace::createWireguardTunnel(std::string wgName) {
|
|
||||||
std::string PathError = createTun((char*)wgName.c_str());
|
|
||||||
if (PathError.rfind("/", 0) != 0) throw PathError;
|
|
||||||
return PathError.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete tunel by name and return true if success
|
|
||||||
void WireguardUserspace::deleteWireguardTunnel(std::string wgName) {
|
|
||||||
std::string deleteStatus = deleteTun((char*)wgName.c_str());
|
|
||||||
if (!deleteStatus.empty()) throw deleteStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> WireguardUserspace::listTunnels() {
|
|
||||||
std::vector<std::string> tunnels;
|
|
||||||
size_t len; char *device_name, *devicesList = listUapis();
|
|
||||||
// Set new devices
|
|
||||||
for (device_name = devicesList, len = 0; (len = strlen(device_name)); device_name += len + 1) tunnels.push_back(std::string(device_name));
|
|
||||||
return tunnels;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WireguardUserspace::checkIfExistTunnel(std::string wgName) {
|
|
||||||
const auto wgTunels = listTunnels();
|
|
||||||
if (wgTunels.size() == 0) return false;
|
|
||||||
for (auto tunelName : wgTunels) {
|
|
||||||
if (tunelName.find_last_of("/") != std::string::npos) tunelName = tunelName.substr(tunelName.find_last_of("/") + 1);
|
|
||||||
if (tunelName.find_last_of(".sock") != std::string::npos) tunelName = tunelName.substr(0, tunelName.find_last_of(".sock"));
|
|
||||||
if (tunelName == wgName) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
@ -37,17 +37,6 @@ bool char_is_digit(int c) {
|
|||||||
return (unsigned int)(('0' - 1 - c) & (c - ('9' + 1))) >> (sizeof(c) * 8 - 1);
|
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() {
|
void WireguardConfig::getWireguardConfig() {
|
||||||
if (this->name.length() == 0) throw std::string("Set wireguard name!");
|
if (this->name.length() == 0) throw std::string("Set wireguard name!");
|
||||||
else if (!(WireguardDevices().exist(this->name))) throw std::string("Wireguard interface not exist");
|
else if (!(WireguardDevices().exist(this->name))) throw std::string("Wireguard interface not exist");
|
||||||
@ -59,7 +48,7 @@ void WireguardConfig::getWireguardConfig() {
|
|||||||
fprintf(f, "get=1\n\n");
|
fprintf(f, "get=1\n\n");
|
||||||
fflush(f);
|
fflush(f);
|
||||||
std::string peerPubKey;
|
std::string peerPubKey;
|
||||||
bool peer;
|
bool peer = false;
|
||||||
|
|
||||||
while (getline(&key, &line_buffer_len, f) > 0) {
|
while (getline(&key, &line_buffer_len, f) > 0) {
|
||||||
line_len = strlen(key);
|
line_len = strlen(key);
|
||||||
@ -71,68 +60,51 @@ void WireguardConfig::getWireguardConfig() {
|
|||||||
if (this->Peers.size() == 0 && !strcmp(key, "private_key")) {
|
if (this->Peers.size() == 0 && !strcmp(key, "private_key")) {
|
||||||
this->privateKey = wgKeys::HextoBase64(value);
|
this->privateKey = wgKeys::HextoBase64(value);
|
||||||
this->publicKey = wgKeys::generatePublic(this->privateKey);
|
this->publicKey = wgKeys::generatePublic(this->privateKey);
|
||||||
} else if (this->Peers.size() == 0 && !strcmp(key, "listen_port")) {
|
} else if (this->Peers.size() == 0 && !strcmp(key, "listen_port")) this->portListen = ({ unsigned long long num; char *end; if (!char_is_digit(value[0])) break; num = strtoull(value, &end, 10); if (*end || num > 0xffffU) break; num; });
|
||||||
this->portListen = NUM(0xffffU);
|
else if (this->Peers.size() == 0 && !strcmp(key, "fwmark")) this->fwmark = ({ unsigned long long num; char *end; if (!char_is_digit(value[0])) break; num = strtoull(value, &end, 10); if (*end || num > 0xffffffffU) break; num; });
|
||||||
} else if (this->Peers.size() == 0 && !strcmp(key, "fwmark")) {
|
else if (!strcmp(key, "public_key")) {
|
||||||
this->fwmark = NUM(0xffffffffU);
|
|
||||||
} else if (!strcmp(key, "public_key")) {
|
|
||||||
Peer new_peer;
|
Peer new_peer;
|
||||||
peerPubKey = wgKeys::HextoBase64(value);
|
peerPubKey = wgKeys::HextoBase64(value);
|
||||||
this->Peers[peerPubKey] = new_peer;
|
this->Peers[peerPubKey] = new_peer;
|
||||||
|
peer = true;
|
||||||
} else if (peer && !strcmp(key, "preshared_key")) {
|
} else if (peer && !strcmp(key, "preshared_key")) {
|
||||||
if (strlen(value) == HexWgKeyLength) this->Peers[peerPubKey].presharedKey = wgKeys::HextoBase64(value);
|
if (std::string(value) == "0000000000000000000000000000000000000000000000000000000000000000") continue;
|
||||||
} else if (peer && !strcmp(key, "endpoint")) {
|
if (strlen(value) == HexWgKeyLength) this->Peers[peerPubKey].presharedKey = wgKeys::HextoBase64(value);
|
||||||
|
} else if (peer && !strcmp(key, "persistent_keepalive_interval")) this->Peers[peerPubKey].keepInterval = ({ unsigned long long num; char *end; if (!char_is_digit(value[0])) break; num = strtoull(value, &end, 10); if (*end || num > 0xffffU) break; num; });
|
||||||
|
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 = ({ unsigned long long num; char *end; if (!char_is_digit(value[0])) break; num = strtoull(value, &end, 10); if (*end || num > 0x7fffffffffffffffULL) break; num; });
|
||||||
|
else if (peer && !strcmp(key, "rx_bytes")) this->Peers[peerPubKey].rxBytes = ({ unsigned long long num; char *end; if (!char_is_digit(value[0])) break; num = strtoull(value, &end, 10); if (*end || num > 0xffffffffffffffffULL) break; num; });
|
||||||
|
else if (peer && !strcmp(key, "tx_bytes")) this->Peers[peerPubKey].txBytes = ({ unsigned long long num; char *end; if (!char_is_digit(value[0])) break; num = strtoull(value, &end, 10); if (*end || num > 0xffffffffffffffffULL) break; num; });
|
||||||
|
else if (!strcmp(key, "errno")) ret = -({ unsigned long long num; char *end; if (!char_is_digit(value[0])) break; num = strtoull(value, &end, 10); if (*end || num > 0x7fffffffU) break; num; });
|
||||||
|
else if (peer && !strcmp(key, "endpoint")) {
|
||||||
char *begin, *end;
|
char *begin, *end;
|
||||||
struct addrinfo *resolved;
|
struct addrinfo *resolved;
|
||||||
struct addrinfo hints = {
|
struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP };
|
||||||
.ai_family = AF_UNSPEC,
|
if (!strlen(value)) break;
|
||||||
.ai_socktype = SOCK_DGRAM,
|
|
||||||
.ai_protocol = IPPROTO_UDP
|
|
||||||
};
|
|
||||||
if (!strlen(value))
|
|
||||||
break;
|
|
||||||
if (value[0] == '[') {
|
if (value[0] == '[') {
|
||||||
begin = &value[1];
|
begin = &value[1];
|
||||||
end = strchr(value, ']');
|
end = strchr(value, ']');
|
||||||
if (!end)
|
if (!end) break;
|
||||||
break;
|
|
||||||
*end++ = '\0';
|
*end++ = '\0';
|
||||||
if (*end++ != ':' || !*end)
|
if (*end++ != ':' || !*end) break;
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
begin = value;
|
begin = value;
|
||||||
end = strrchr(value, ':');
|
end = strrchr(value, ':');
|
||||||
if (!end || !*(end + 1))
|
if (!end || !*(end + 1)) break;
|
||||||
break;
|
|
||||||
*end++ = '\0';
|
*end++ = '\0';
|
||||||
}
|
}
|
||||||
if (getaddrinfo(begin, end, &hints, &resolved) != 0) {
|
if (getaddrinfo(begin, end, &hints, &resolved) != 0) {
|
||||||
ret = ENETUNREACH;
|
ret = ENETUNREACH;
|
||||||
throw std::string("Failed to resolve endpoint");
|
throw std::string("Failed to resolve endpoint");
|
||||||
}
|
}
|
||||||
if ((resolved->ai_family == AF_INET && resolved->ai_addrlen == sizeof(struct sockaddr_in))
|
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;
|
||||||
|| (resolved->ai_family == AF_INET6 && resolved->ai_addrlen == sizeof(struct sockaddr_in6)))
|
else {
|
||||||
this->Peers[peerPubKey].endpoint = value;
|
|
||||||
else {
|
|
||||||
freeaddrinfo(resolved);
|
freeaddrinfo(resolved);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
freeaddrinfo(resolved);
|
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);
|
free(key);
|
||||||
@ -144,11 +116,60 @@ void WireguardConfig::setWireguardConfig() {
|
|||||||
if (this->name.length() == 0) throw std::string("Set wireguard name!");
|
if (this->name.length() == 0) throw std::string("Set wireguard name!");
|
||||||
else if (!(WireguardDevices().exist(this->name))) {
|
else if (!(WireguardDevices().exist(this->name))) {
|
||||||
std::string PathError = createTun((char*)this->name.c_str());
|
std::string PathError = createTun((char*)this->name.c_str());
|
||||||
if (PathError.rfind("/", 0) != 0) throw PathError;
|
if (PathError.size() > 0) throw PathError;
|
||||||
}
|
}
|
||||||
FILE *f = interfaceFile(WireguardDevices().findSock(this->name).c_str());
|
|
||||||
if (!f) throw std::string("Failed to open interface file");
|
FILE* f = interfaceFile(WireguardDevices().findSock(this->name));
|
||||||
|
fprintf(f, "set=1\n");
|
||||||
|
|
||||||
|
if (this->privateKey.length() == Base64WgKeyLength) fprintf(f, "private_key=%s\n", wgKeys::toHex(this->privateKey).c_str());
|
||||||
|
if (this->portListen >= 0) fprintf(f, "listen_port=%u\n", this->portListen);
|
||||||
|
if (this->fwmark >= 0) fprintf(f, "fwmark=%u\n", this->fwmark);
|
||||||
|
if (this->replacePeers) fprintf(f, "replace_peers=true\n");
|
||||||
|
|
||||||
|
for (auto peer : this->Peers) {
|
||||||
|
fprintf(f, "public_key=%s\n", wgKeys::toHex(peer.first).c_str());
|
||||||
|
if (peer.second.removeMe) {
|
||||||
|
fprintf(f, "remove=true\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (peer.second.presharedKey.length() == Base64WgKeyLength) fprintf(f, "preshared_key=%s\n", wgKeys::toHex(peer.second.presharedKey).c_str());
|
||||||
|
if (peer.second.keepInterval) fprintf(f, "persistent_keepalive_interval=%u\n", peer.second.keepInterval);
|
||||||
|
if (peer.second.endpoint.length() > 2) fprintf(f, "endpoint=%s\n", peer.second.endpoint.c_str());
|
||||||
|
if (peer.second.allowedIPs.size() > 0) {
|
||||||
|
fprintf(f, "replace_allowed_ips=true\n");
|
||||||
|
for (auto s : peer.second.allowedIPs.getIpParsed()) fprintf(f, "allowed_ip=%s/%d\n", s.Address.c_str(), s.Mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f, "\n");
|
||||||
|
fflush(f);
|
||||||
|
|
||||||
|
int ret, set_errno = -EPROTO;
|
||||||
|
size_t line_buffer_len = 0, line_len;
|
||||||
|
char *key = NULL, *value;
|
||||||
|
while (getline(&key, &line_buffer_len, f) > 0) {
|
||||||
|
line_len = strlen(key);
|
||||||
|
ret = set_errno;
|
||||||
|
if (line_len == 1 && key[0] == '\n') break;
|
||||||
|
value = strchr(key, '=');
|
||||||
|
if (!value || line_len == 0 || key[line_len - 1] != '\n') break;
|
||||||
|
*value++ = key[--line_len] = '\0';
|
||||||
|
|
||||||
|
if (!strcmp(key, "errno")) {
|
||||||
|
long long num;
|
||||||
|
char *end;
|
||||||
|
if (value[0] != '-' && !char_is_digit(value[0])) break;
|
||||||
|
num = strtoll(value, &end, 10);
|
||||||
|
if (*end || num > INT_MAX || num < INT_MIN) break;
|
||||||
|
set_errno = num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(key);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
ret = -(errno ? -errno : -EPROTO);
|
||||||
|
if (ret < 0) throw std::string("Cannot set configuration, code: ").append(std::to_string(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpManeger::SetInInterface(std::string interfaceName) {}
|
void IpManeger::SetInInterface(std::string interfaceName) {}
|
||||||
|
@ -26,13 +26,10 @@ 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) {
|
else {
|
||||||
wgDev->erase(wgDev->find_last_of(".sock"));
|
std::string __nDev = std::string(wgDev->substr(wgDev->find_last_of("/")+1));
|
||||||
if (name == *wgDev) return true;
|
if (__nDev.find(".sock") != std::string::npos) __nDev = __nDev.substr(0, __nDev.find(".sock"));
|
||||||
if (wgDev->find_last_of("/wg") != std::string::npos) {
|
if (__nDev == name) return true;
|
||||||
wgDev->erase(wgDev->find_last_of("/wg"));
|
|
||||||
if (name == *wgDev) return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,12 +42,9 @@ class WireguardDevices : public std::vector<std::string> {
|
|||||||
for (auto wgDev = this->begin(); wgDev != this->end(); ++wgDev) {
|
for (auto wgDev = this->begin(); wgDev != this->end(); ++wgDev) {
|
||||||
if (name == *wgDev) return *wgDev;
|
if (name == *wgDev) return *wgDev;
|
||||||
else if (wgDev->find_last_of(".sock") != std::string::npos) {
|
else if (wgDev->find_last_of(".sock") != std::string::npos) {
|
||||||
wgDev->erase(wgDev->find_last_of(".sock"));
|
std::string __nDev = std::string(wgDev->substr(wgDev->find_last_of("/")+1));
|
||||||
if (name == *wgDev) return *wgDev;
|
if (__nDev.find(".sock") != std::string::npos) __nDev = __nDev.substr(0, __nDev.find(".sock"));
|
||||||
if (wgDev->find_last_of("/wg") != std::string::npos) {
|
if (__nDev == name) return *wgDev;
|
||||||
wgDev->erase(wgDev->find_last_of("/wg"));
|
|
||||||
if (name == *wgDev) return *wgDev;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import test from "node:test";
|
import test from "node:test";
|
||||||
import { Wireguard } from "./wginterface.js";
|
import { Wireguard, getConfig, setConfig } from "./wginterface.js";
|
||||||
import { presharedKey, privateKey, publicKey } from "./key.js";
|
import { presharedKey, privateKey, publicKey } from "./key.js";
|
||||||
|
import assert from "node:assert";
|
||||||
|
|
||||||
await test("Wireguard interface", async t => {
|
await test("Wireguard interface", async t => {
|
||||||
const config = new Wireguard;
|
const config = new Wireguard;
|
||||||
@ -28,11 +29,22 @@ await test("Wireguard interface", async t => {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const jsonConfig = config.toJSON();
|
||||||
|
|
||||||
let skip: string;
|
let skip: string;
|
||||||
await t.test("Create and Set config in interface", async () => config.deploy().catch(err => { skip = "Cannot set wireguard config"; return Promise.reject(err); }));
|
await t.test("Create and Set config in interface", async () => setConfig(jsonConfig).catch(err => { skip = "Cannot set wireguard config"; return Promise.reject(err); }));
|
||||||
await t.test("Get config from interface", { skip }, async () => {
|
await t.test("Get config from interface", { skip }, async () => {
|
||||||
await config.getConfig();
|
const config = await getConfig(jsonConfig.name);
|
||||||
console.dir(config.toJSON(), { depth: null });
|
// console.dir(config, { depth: null });
|
||||||
|
|
||||||
|
if (!config.peers[publicKey(peer1)]) throw new Error("Peer not exists in interface");
|
||||||
|
if (!config.peers[publicKey(peer2)]) throw new Error("Peer not exists in interface");
|
||||||
|
|
||||||
|
assert.equal(config.peers[publicKey(peer1)].keepInterval, jsonConfig.peers[publicKey(peer1)].keepInterval);
|
||||||
|
assert.equal(config.peers[publicKey(peer1)].presharedKey, jsonConfig.peers[publicKey(peer1)].presharedKey);
|
||||||
|
|
||||||
|
assert.deepEqual(config.peers[publicKey(peer1)].allowedIPs, jsonConfig.peers[publicKey(peer1)].allowedIPs);
|
||||||
|
assert.deepEqual(config.peers[publicKey(peer2)].allowedIPs, jsonConfig.peers[publicKey(peer2)].allowedIPs);
|
||||||
});
|
});
|
||||||
|
|
||||||
await t.test("Delete interface if exists", { skip }, async () => config.delete());
|
await t.test("Delete interface if exists", { skip }, async () => config.delete());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user