Add clang-format #4
236
.clang-format
Normal file
236
.clang-format
Normal file
@ -0,0 +1,236 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: true
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCaseColons: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 0
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterExternBlock: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakAfterAttributes: Never
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakArrays: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInlineASMColon: OnlyMultiline
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: false
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: false
|
||||
InsertNewlineAtEOF: false
|
||||
InsertTrailingCommas: None
|
||||
IntegerLiteralSeparator:
|
||||
Binary: 0
|
||||
BinaryMinDigits: 0
|
||||
Decimal: 0
|
||||
DecimalMinDigits: 0
|
||||
Hex: 0
|
||||
HexMinDigits: 0
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
KeepEmptyLinesAtEOF: false
|
||||
LambdaBodyIndentation: Signature
|
||||
LineEnding: DeriveLF
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PackConstructorInitializers: BinPack
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
QualifierAlignment: Leave
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
RemoveBracesLLVM: false
|
||||
RemoveParentheses: Leave
|
||||
RemoveSemicolon: false
|
||||
RequiresClausePosition: OwnLine
|
||||
RequiresExpressionIndentation: OuterScope
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: LexicographicNumeric
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeJsonColon: false
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParens: Never
|
||||
SpacesInParensOptions:
|
||||
InCStyleCasts: false
|
||||
InConditionalStatements: false
|
||||
InEmptyParentheses: false
|
||||
Other: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
VerilogBreakBetweenInstancePorts: true
|
||||
WhitespaceSensitiveMacros:
|
||||
- BOOST_PP_STRINGIZE
|
||||
- CF_SWIFT_NAME
|
||||
- NS_SWIFT_NAME
|
||||
- PP_STRINGIZE
|
||||
- STRINGIZE
|
||||
...
|
||||
|
21
.github/workflows/format.yml
vendored
Normal file
21
.github/workflows/format.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: Test
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
name: Checkout
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt update
|
||||
sudo apt install -y clang-format
|
||||
|
||||
- name: format C/C++ code
|
||||
run: find addons/ -path addons/tools/linux -prune -o -regex '.*\.\(cpp\|hpp\|cc\|c\|h\)' -exec clang-format -style=file -i {} \;
|
||||
|
||||
- run: git diff --exit-code --quiet HEAD~1 -- .
|
@ -1,10 +1,11 @@
|
||||
#include <napi.h>
|
||||
#include "wgkeys.hh"
|
||||
#include <napi.h>
|
||||
|
||||
class privateKeyWorker : public Napi::AsyncWorker {
|
||||
private:
|
||||
std::string pskString;
|
||||
Napi::Promise::Deferred genPromise;
|
||||
|
||||
public:
|
||||
~privateKeyWorker() {}
|
||||
privateKeyWorker(const Napi::Env env) : AsyncWorker(env), genPromise{env} {}
|
||||
@ -28,9 +29,11 @@ class publicKeyWorker : public Napi::AsyncWorker {
|
||||
private:
|
||||
std::string privKey, pubString;
|
||||
Napi::Promise::Deferred genPromise;
|
||||
|
||||
public:
|
||||
~publicKeyWorker() {}
|
||||
publicKeyWorker(const Napi::Env env, std::string privateKey) : AsyncWorker(env), privKey(privateKey), genPromise{env} {}
|
||||
publicKeyWorker(const Napi::Env env, std::string privateKey)
|
||||
: AsyncWorker(env), privKey(privateKey), genPromise{env} {}
|
||||
Napi::Promise getPromise() { return genPromise.Promise(); }
|
||||
void Execute() override {
|
||||
wg_key interfacePrivateKey, interfacePublicKey;
|
||||
@ -56,6 +59,7 @@ class presharedKeyWorker : public Napi::AsyncWorker {
|
||||
private:
|
||||
std::string pskString;
|
||||
Napi::Promise::Deferred genPromise;
|
||||
|
||||
public:
|
||||
~presharedKeyWorker() {}
|
||||
presharedKeyWorker(const Napi::Env env) : AsyncWorker(env), genPromise{env} {}
|
||||
@ -80,9 +84,11 @@ class genKeysWorker : public Napi::AsyncWorker {
|
||||
std::string privateKey, publicKey, presharedKey;
|
||||
bool withPreshared = false;
|
||||
Napi::Promise::Deferred genPromise;
|
||||
|
||||
public:
|
||||
~genKeysWorker() {}
|
||||
genKeysWorker(const Napi::Env env, bool withPresharedKey) : AsyncWorker(env), withPreshared(withPresharedKey), genPromise{env} {}
|
||||
genKeysWorker(const Napi::Env env, bool withPresharedKey)
|
||||
: AsyncWorker(env), withPreshared(withPresharedKey), genPromise{env} {}
|
||||
Napi::Promise getPromise() { return genPromise.Promise(); }
|
||||
void Execute() override {
|
||||
wg_key keyPriv, preshe, pub;
|
||||
@ -93,7 +99,8 @@ class genKeysWorker : public Napi::AsyncWorker {
|
||||
wgKeys::generatePublic(pub, keyPriv);
|
||||
publicKey = wgKeys::toString(pub);
|
||||
|
||||
if (!withPreshared) return;
|
||||
if (!withPreshared)
|
||||
return;
|
||||
wgKeys::generatePreshared(preshe);
|
||||
presharedKey = wgKeys::toString(preshe);
|
||||
}
|
||||
@ -103,7 +110,8 @@ class genKeysWorker : public Napi::AsyncWorker {
|
||||
auto keys = Napi::Object::New(env);
|
||||
keys.Set("privateKey", privateKey);
|
||||
keys.Set("publicKey", publicKey);
|
||||
if (withPreshared) keys.Set("presharedKey", presharedKey);
|
||||
if (withPreshared)
|
||||
keys.Set("presharedKey", presharedKey);
|
||||
|
||||
genPromise.Resolve(keys);
|
||||
}
|
||||
@ -119,7 +127,9 @@ Napi::Object Init(Napi::Env exportsEnv, Napi::Object exports) {
|
||||
constants.Set("B64_WG_KEY_LENGTH", B64_WG_KEY_LENGTH);
|
||||
exports.Set("constants", constants);
|
||||
|
||||
exports.Set("presharedKey", Napi::Function::New(exportsEnv, [&](const Napi::CallbackInfo& info) {
|
||||
exports.Set(
|
||||
"presharedKey",
|
||||
Napi::Function::New(exportsEnv, [&](const Napi::CallbackInfo &info) {
|
||||
const Napi::Env env = info.Env();
|
||||
|
||||
// Callback function is latest argument
|
||||
@ -128,7 +138,9 @@ Napi::Object Init(Napi::Env exportsEnv, Napi::Object exports) {
|
||||
return Gen->getPromise();
|
||||
}));
|
||||
|
||||
exports.Set("privateKey", Napi::Function::New(exportsEnv, [&](const Napi::CallbackInfo& info) {
|
||||
exports.Set(
|
||||
"privateKey",
|
||||
Napi::Function::New(exportsEnv, [&](const Napi::CallbackInfo &info) {
|
||||
const Napi::Env env = info.Env();
|
||||
|
||||
// Callback function is latest argument
|
||||
@ -137,23 +149,30 @@ Napi::Object Init(Napi::Env exportsEnv, Napi::Object exports) {
|
||||
return Gen->getPromise();
|
||||
}));
|
||||
|
||||
exports.Set("publicKey", Napi::Function::New(exportsEnv, [&](const Napi::CallbackInfo& info) -> Napi::Value {
|
||||
exports.Set(
|
||||
"publicKey",
|
||||
Napi::Function::New(exportsEnv,
|
||||
[&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
const Napi::Env env = info.Env();
|
||||
if (!(info[0].IsString())) {
|
||||
Napi::Error::New(env, "Require private key").ThrowAsJavaScriptException();
|
||||
Napi::Error::New(env, "Require private key")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
// Callback function is latest argument
|
||||
auto *Gen = new publicKeyWorker(env, info[0].ToString().Utf8Value().c_str());
|
||||
auto *Gen = new publicKeyWorker(
|
||||
env, info[0].ToString().Utf8Value().c_str());
|
||||
Gen->Queue();
|
||||
return Gen->getPromise();
|
||||
}));
|
||||
|
||||
exports.Set("genKey", Napi::Function::New(exportsEnv, [&](const Napi::CallbackInfo &info) {
|
||||
exports.Set("genKey", Napi::Function::New(
|
||||
exportsEnv, [&](const Napi::CallbackInfo &info) {
|
||||
const Napi::Env env = info.Env();
|
||||
bool withPreshared = false;
|
||||
if (info[0].IsBoolean()) withPreshared = info[0].ToBoolean().Value();
|
||||
if (info[0].IsBoolean())
|
||||
withPreshared = info[0].ToBoolean().Value();
|
||||
auto Gen = new genKeysWorker(env, withPreshared);
|
||||
Gen->Queue();
|
||||
return Gen->getPromise();
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "wgkeys.hh"
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
@ -18,16 +18,19 @@ static void encode_base64(char dest[4], const uint8_t src[3]) {
|
||||
static_cast<uint8_t>((src[0] >> 2) & 63),
|
||||
static_cast<uint8_t>(((src[0] << 4) | (src[1] >> 4)) & 63),
|
||||
static_cast<uint8_t>(((src[1] << 2) | (src[2] >> 6)) & 63),
|
||||
static_cast<uint8_t>(src[2] & 63)
|
||||
};
|
||||
static_cast<uint8_t>(src[2] & 63)};
|
||||
unsigned int i;
|
||||
for (i = 0; i < 4; ++i) dest[i] = input[i] + 'A' + (((25 - input[i]) >> 8) & 6) - (((51 - input[i]) >> 8) & 75) - (((61 - input[i]) >> 8) & 15) + (((62 - input[i]) >> 8) & 3);
|
||||
for (i = 0; i < 4; ++i)
|
||||
dest[i] = input[i] + 'A' + (((25 - input[i]) >> 8) & 6) -
|
||||
(((51 - input[i]) >> 8) & 75) - (((61 - input[i]) >> 8) & 15) +
|
||||
(((62 - input[i]) >> 8) & 3);
|
||||
}
|
||||
|
||||
void keyToBase64(wg_key_b64_string base64, const wg_key key) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 32 / 3; ++i) encode_base64(&base64[i * 4], &key[i * 3]);
|
||||
for (i = 0; i < 32 / 3; ++i)
|
||||
encode_base64(&base64[i * 4], &key[i * 3]);
|
||||
const uint8_t tempKey[3] = {key[i * 3 + 0], key[i * 3 + 1], 0};
|
||||
encode_base64(&base64[i * 4], tempKey);
|
||||
base64[sizeof(wg_key_b64_string) - 2] = '=';
|
||||
@ -38,15 +41,24 @@ static int decodeBase64(const char src[4]) {
|
||||
int val = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 4; ++i) val |= (-1 + ((((('A' - 1) - src[i]) & (src[i] - ('Z' + 1))) >> 8) & (src[i] - 64)) + ((((('a' - 1) - src[i]) & (src[i] - ('z' + 1))) >> 8) & (src[i] - 70)) + ((((('0' - 1) - src[i]) & (src[i] - ('9' + 1))) >> 8) & (src[i] + 5)) + ((((('+' - 1) - src[i]) & (src[i] - ('+' + 1))) >> 8) & 63) + ((((('/' - 1) - src[i]) & (src[i] - ('/' + 1))) >> 8) & 64)) << (18 - 6 * i);
|
||||
for (i = 0; i < 4; ++i)
|
||||
val |=
|
||||
(-1 +
|
||||
((((('A' - 1) - src[i]) & (src[i] - ('Z' + 1))) >> 8) &
|
||||
(src[i] - 64)) +
|
||||
((((('a' - 1) - src[i]) & (src[i] - ('z' + 1))) >> 8) &
|
||||
(src[i] - 70)) +
|
||||
((((('0' - 1) - src[i]) & (src[i] - ('9' + 1))) >> 8) & (src[i] + 5)) +
|
||||
((((('+' - 1) - src[i]) & (src[i] - ('+' + 1))) >> 8) & 63) +
|
||||
((((('/' - 1) - src[i]) & (src[i] - ('/' + 1))) >> 8) & 64))
|
||||
<< (18 - 6 * i);
|
||||
return val;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static volatile void * (*memset_func)(void *, int, size_t) = (volatile void * (*)(void *, int, size_t))&memset;
|
||||
void memzero_explicit(void *s, size_t count) {
|
||||
memset_func(s, 0, count);
|
||||
}
|
||||
static volatile void *(*memset_func)(void *, int, size_t) =
|
||||
(volatile void *(*)(void *, int, size_t)) & memset;
|
||||
void memzero_explicit(void *s, size_t count) { memset_func(s, 0, count); }
|
||||
#else
|
||||
static __attribute__((noinline)) void memzero_explicit(void *s, size_t count) {
|
||||
memset(s, 0, count);
|
||||
@ -109,21 +121,25 @@ static void pack(uint8_t *o, const fe n) {
|
||||
|
||||
static void add(fe o, const fe a, const fe b) {
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i) o[i] = a[i] + b[i];
|
||||
for (i = 0; i < 16; ++i)
|
||||
o[i] = a[i] + b[i];
|
||||
}
|
||||
|
||||
static void subtract(fe o, const fe a, const fe b) {
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i) o[i] = a[i] - b[i];
|
||||
for (i = 0; i < 16; ++i)
|
||||
o[i] = a[i] - b[i];
|
||||
}
|
||||
|
||||
static void multmod(fe o, const fe a, const fe b) {
|
||||
int i, j;
|
||||
int64_t t[31] = {0};
|
||||
for (i = 0; i < 16; ++i) {
|
||||
for (j = 0; j < 16; ++j) t[i + j] += a[i] * b[j];
|
||||
for (j = 0; j < 16; ++j)
|
||||
t[i + j] += a[i] * b[j];
|
||||
}
|
||||
for (i = 0; i < 15; ++i) t[i] += 38 * t[i + 16];
|
||||
for (i = 0; i < 15; ++i)
|
||||
t[i] += 38 * t[i + 16];
|
||||
memcpy(o, t, sizeof(fe));
|
||||
carry(o);
|
||||
carry(o);
|
||||
@ -136,7 +152,8 @@ static void invert(fe o, const fe i) {
|
||||
memcpy(c, i, sizeof(c));
|
||||
for (a = 253; a >= 0; --a) {
|
||||
multmod(c, c, c);
|
||||
if (a != 2 && a != 4) multmod(c, c, i);
|
||||
if (a != 2 && a != 4)
|
||||
multmod(c, c, i);
|
||||
}
|
||||
memcpy(o, c, sizeof(fe));
|
||||
memzero_explicit(c, sizeof(c));
|
||||
@ -146,15 +163,26 @@ void wgKeys::generatePreshared(wg_key preshared_key) {
|
||||
#if _WIN32 || defined(__CYGWIN__)
|
||||
HCRYPTPROV hCryptProv;
|
||||
BOOL winStatus;
|
||||
if ((winStatus = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))) winStatus = CryptGenRandom(hCryptProv, sizeof(wg_key), (BYTE*)preshared_key);
|
||||
if ((winStatus = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT)))
|
||||
winStatus =
|
||||
CryptGenRandom(hCryptProv, sizeof(wg_key), (BYTE *)preshared_key);
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
if (winStatus) return;
|
||||
if (winStatus)
|
||||
return;
|
||||
|
||||
#elif defined(__OpenBSD__) || (defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) || (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))
|
||||
if (!getentropy(preshared_key, sizeof(wg_key))) return;
|
||||
#elif defined(__OpenBSD__) || \
|
||||
(defined(__APPLE__) && \
|
||||
MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) || \
|
||||
(defined(__GLIBC__) && \
|
||||
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))
|
||||
if (!getentropy(preshared_key, sizeof(wg_key)))
|
||||
return;
|
||||
|
||||
#elif defined(__NR_getrandom) && defined(__linux__)
|
||||
if (syscall(__NR_getrandom, preshared_key, sizeof(wg_key), 0) == sizeof(wg_key)) return;
|
||||
if (syscall(__NR_getrandom, preshared_key, sizeof(wg_key), 0) ==
|
||||
sizeof(wg_key))
|
||||
return;
|
||||
|
||||
#elif __linux__ || _ANDROID__ || __termux__
|
||||
size_t ret, i;
|
||||
@ -237,8 +265,7 @@ void wgKeys::generatePublic(wg_key public_key, const wg_key private_key) {
|
||||
memzero_explicit(f, sizeof(f));
|
||||
}
|
||||
|
||||
bool key_is_zero(const uint8_t key[32])
|
||||
{
|
||||
bool key_is_zero(const uint8_t key[32]) {
|
||||
volatile uint8_t acc = 0;
|
||||
|
||||
for (unsigned int i = 0; i < 32; ++i) {
|
||||
@ -250,7 +277,10 @@ bool key_is_zero(const uint8_t key[32])
|
||||
|
||||
void wgKeys::stringToKey(wg_key key, std::string keyBase64) {
|
||||
auto base64 = keyBase64.c_str();
|
||||
if (keyBase64.length() != B64_WG_KEY_LENGTH || base64[B64_WG_KEY_LENGTH - 1] != '=') throw std::string("invalid key, length: ").append(std::to_string(keyBase64.length()));
|
||||
if (keyBase64.length() != B64_WG_KEY_LENGTH ||
|
||||
base64[B64_WG_KEY_LENGTH - 1] != '=')
|
||||
throw std::string("invalid key, length: ")
|
||||
.append(std::to_string(keyBase64.length()));
|
||||
|
||||
unsigned int i;
|
||||
int val;
|
||||
@ -263,20 +293,24 @@ void wgKeys::stringToKey(wg_key key, std::string keyBase64) {
|
||||
key[i * 3 + 1] = (val >> 8) & 0xff;
|
||||
key[i * 3 + 2] = val & 0xff;
|
||||
}
|
||||
const char tempDecode[4] = {base64[i * 4 + 0], base64[i * 4 + 1], base64[i * 4 + 2], 'A'};
|
||||
const char tempDecode[4] = {base64[i * 4 + 0], base64[i * 4 + 1],
|
||||
base64[i * 4 + 2], 'A'};
|
||||
val = decodeBase64(tempDecode);
|
||||
ret |= ((uint32_t)val >> 31) | (val & 0xff);
|
||||
key[i * 3 + 0] = (val >> 16) & 0xff;
|
||||
key[i * 3 + 1] = (val >> 8) & 0xff;
|
||||
int status = EINVAL & ~((ret - 1) >> 8);
|
||||
if (status != 0) throw std::string("Cannot decode key, ret code: ").append(std::to_string(status));
|
||||
if (status != 0)
|
||||
throw std::string("Cannot decode key, ret code: ")
|
||||
.append(std::to_string(status));
|
||||
}
|
||||
|
||||
std::string wgKeys::toString(const wg_key key) {
|
||||
wg_key_b64_string base64;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 32 / 3; ++i) encode_base64(&base64[i * 4], &key[i * 3]);
|
||||
for (i = 0; i < 32 / 3; ++i)
|
||||
encode_base64(&base64[i * 4], &key[i * 3]);
|
||||
const uint8_t tempKey[3] = {key[i * 3 + 0], key[i * 3 + 1], 0};
|
||||
encode_base64(&base64[i * 4], tempKey);
|
||||
base64[sizeof(wg_key_b64_string) - 2] = '=';
|
||||
|
@ -1,14 +1,10 @@
|
||||
#include <napi.h>
|
||||
#include <wginterface.hh>
|
||||
#include <net/if.h>
|
||||
#include <wginterface.hh>
|
||||
|
||||
unsigned long maxName() {
|
||||
return IFNAMSIZ;
|
||||
}
|
||||
unsigned long maxName() { return IFNAMSIZ; }
|
||||
|
||||
std::string versionDrive() {
|
||||
return "Userspace";
|
||||
}
|
||||
std::string versionDrive() { return "Userspace"; }
|
||||
|
||||
void listDevices::Execute() {}
|
||||
void deleteInterface::Execute() {}
|
||||
|
@ -1,29 +1,28 @@
|
||||
#include <napi.h>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "linux/set_ip.cpp"
|
||||
#include "wginterface.hh"
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <cerrno>
|
||||
#include <ifaddrs.h>
|
||||
#include <iostream>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <napi.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <sysexits.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include "wginterface.hh"
|
||||
#include "linux/set_ip.cpp"
|
||||
#include <sysexits.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
extern "C" {
|
||||
#include "linux/wireguard.h"
|
||||
}
|
||||
@ -33,19 +32,17 @@ extern "C" {
|
||||
#define LISTDEV 1
|
||||
#define DELIFACE 1
|
||||
|
||||
unsigned long maxName() {
|
||||
return IFNAMSIZ;
|
||||
}
|
||||
unsigned long maxName() { return IFNAMSIZ; }
|
||||
|
||||
std::string versionDrive() {
|
||||
return "Kernel";
|
||||
}
|
||||
std::string versionDrive() { return "Kernel"; }
|
||||
|
||||
void listDevices::Execute() {
|
||||
char *device_name, *devicesList = wg_list_device_names();
|
||||
if (!devicesList) return SetError("Unable to get device names");
|
||||
if (!devicesList)
|
||||
return SetError("Unable to get device names");
|
||||
size_t len;
|
||||
for ((device_name) = (devicesList), (len) = 0; ((len) = strlen(device_name)); (device_name) += (len) + 1) {
|
||||
for ((device_name) = (devicesList), (len) = 0; ((len) = strlen(device_name));
|
||||
(device_name) += (len) + 1) {
|
||||
listInfo setInfo;
|
||||
setInfo.tunType = "kernel";
|
||||
deviceNames[std::string(device_name)] = setInfo;
|
||||
@ -58,7 +55,8 @@ int setInterface(std::string wgName) {
|
||||
char *device_name, *devicesList = wg_list_device_names();
|
||||
if (!!devicesList) {
|
||||
auto createInterface = true;
|
||||
for ((device_name) = (devicesList), (len) = 0; ((len) = strlen(device_name)); (device_name) += (len) + 1) {
|
||||
for ((device_name) = (devicesList), (len) = 0;
|
||||
((len) = strlen(device_name)); (device_name) += (len) + 1) {
|
||||
if (device_name == wgName.c_str()) {
|
||||
createInterface = false;
|
||||
break;
|
||||
@ -66,7 +64,8 @@ int setInterface(std::string wgName) {
|
||||
}
|
||||
free(devicesList);
|
||||
len = 0;
|
||||
if (createInterface) len = wg_add_device(wgName.c_str());
|
||||
if (createInterface)
|
||||
len = wg_add_device(wgName.c_str());
|
||||
}
|
||||
|
||||
return len;
|
||||
@ -76,13 +75,17 @@ void deleteInterface::Execute() {
|
||||
size_t len = 0;
|
||||
char *device_name, *devicesList = wg_list_device_names();
|
||||
if (!!devicesList) {
|
||||
for ((device_name) = (devicesList), (len) = 0; ((len) = strlen(device_name)); (device_name) += (len) + 1) {
|
||||
for ((device_name) = (devicesList), (len) = 0;
|
||||
((len) = strlen(device_name)); (device_name) += (len) + 1) {
|
||||
if (device_name == wgName.c_str()) {
|
||||
if ((len = wg_add_device(wgName.c_str())) < 0) {
|
||||
std::string err = "Error code: ";
|
||||
err = err.append(std::to_string(len));
|
||||
if (len == -ENOMEM) err = "Out of memory";
|
||||
else if (len == -errno) err = ((std::string)"Cannot add device, code: ").append(std::to_string(len));
|
||||
if (len == -ENOMEM)
|
||||
err = "Out of memory";
|
||||
else if (len == -errno)
|
||||
err = ((std::string) "Cannot add device, code: ")
|
||||
.append(std::to_string(len));
|
||||
SetError(err);
|
||||
}
|
||||
break;
|
||||
@ -97,8 +100,11 @@ void setConfig::Execute() {
|
||||
if (res < 0) {
|
||||
std::string err = "Error code: ";
|
||||
err = err.append(std::to_string(res));
|
||||
if (res == -ENOMEM) err = "Out of memory";
|
||||
else if (res == -errno) err = ((std::string)"Cannot add device, code: ").append(std::to_string(res));
|
||||
if (res == -ENOMEM)
|
||||
err = "Out of memory";
|
||||
else if (res == -errno)
|
||||
err = ((std::string) "Cannot add device, code: ")
|
||||
.append(std::to_string(res));
|
||||
SetError(err);
|
||||
return;
|
||||
}
|
||||
@ -120,17 +126,21 @@ void setConfig::Execute() {
|
||||
// Port listenings
|
||||
if (portListen > 0 && 25565 < portListen) {
|
||||
deviceStruct->listen_port = portListen;
|
||||
deviceStruct->flags = (wg_device_flags)(deviceStruct->flags|WGDEVICE_HAS_LISTEN_PORT);
|
||||
deviceStruct->flags =
|
||||
(wg_device_flags)(deviceStruct->flags | WGDEVICE_HAS_LISTEN_PORT);
|
||||
}
|
||||
|
||||
// Linux firewall mark
|
||||
if (fwmark >= 0) {
|
||||
deviceStruct->fwmark = fwmark;
|
||||
deviceStruct->flags = (wg_device_flags)(deviceStruct->flags|WGDEVICE_HAS_FWMARK);
|
||||
deviceStruct->flags =
|
||||
(wg_device_flags)(deviceStruct->flags | WGDEVICE_HAS_FWMARK);
|
||||
}
|
||||
|
||||
// Replace Peers
|
||||
if (replacePeers) deviceStruct->flags = (wg_device_flags)(deviceStruct->flags|WGDEVICE_REPLACE_PEERS);
|
||||
if (replacePeers)
|
||||
deviceStruct->flags =
|
||||
(wg_device_flags)(deviceStruct->flags | WGDEVICE_REPLACE_PEERS);
|
||||
|
||||
unsigned int peerIndex = 0;
|
||||
for (auto it = peersVector.begin(); it != peersVector.end(); ++it) {
|
||||
@ -144,18 +154,23 @@ void setConfig::Execute() {
|
||||
peerStruct->flags = (wg_peer_flags)WGPEER_HAS_PUBLIC_KEY;
|
||||
|
||||
// Remove Peer
|
||||
if (peerConfig.removeMe) peerStruct->flags = (wg_peer_flags)(peerStruct->flags|WGPEER_REMOVE_ME);
|
||||
if (peerConfig.removeMe)
|
||||
peerStruct->flags = (wg_peer_flags)(peerStruct->flags | WGPEER_REMOVE_ME);
|
||||
else {
|
||||
// Set preshared key if present
|
||||
if (peerConfig.presharedKey.length() > 0) {
|
||||
wg_key_from_base64(peerStruct->preshared_key, peerConfig.presharedKey.c_str());
|
||||
peerStruct->flags = (wg_peer_flags)(peerStruct->flags|WGPEER_HAS_PRESHARED_KEY);
|
||||
wg_key_from_base64(peerStruct->preshared_key,
|
||||
peerConfig.presharedKey.c_str());
|
||||
peerStruct->flags =
|
||||
(wg_peer_flags)(peerStruct->flags | WGPEER_HAS_PRESHARED_KEY);
|
||||
}
|
||||
|
||||
// Set Keepalive
|
||||
if (peerConfig.keepInterval > 0) {
|
||||
peerStruct->persistent_keepalive_interval = peerConfig.keepInterval;
|
||||
peerStruct->flags = (wg_peer_flags)(peerStruct->flags|WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL);
|
||||
peerStruct->flags =
|
||||
(wg_peer_flags)(peerStruct->flags |
|
||||
WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL);
|
||||
}
|
||||
|
||||
// Set endpoint
|
||||
@ -195,32 +210,46 @@ void setConfig::Execute() {
|
||||
ai_protocol : IPPROTO_UDP
|
||||
};
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
for (unsigned int timeout = 1000000;; timeout = min(20000000, timeout * 6 / 5)) {
|
||||
for (unsigned int timeout = 1000000;;
|
||||
timeout = min(20000000, timeout * 6 / 5)) {
|
||||
ret = getaddrinfo(begin, end, &hints, &resolved);
|
||||
if (!ret) break;
|
||||
if (!ret)
|
||||
break;
|
||||
if (ret == EAI_NONAME || ret == EAI_FAIL ||
|
||||
#ifdef EAI_NODATA
|
||||
ret == EAI_NODATA ||
|
||||
#endif
|
||||
(retries >= 0 && !retries--)) {
|
||||
free(Endpoint);
|
||||
fprintf(stderr, "%s: `%s'\n", ret == EAI_SYSTEM ? strerror(errno) : gai_strerror(ret), peerConfig.endpoint.c_str());
|
||||
fprintf(stderr, "%s: `%s'\n",
|
||||
ret == EAI_SYSTEM ? strerror(errno) : gai_strerror(ret),
|
||||
peerConfig.endpoint.c_str());
|
||||
SetError("Unable to resolve endpoint");
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "%s: `%s'. Trying again in %.2f seconds...\n", ret == EAI_SYSTEM ? strerror(errno) : gai_strerror(ret), peerConfig.endpoint.c_str(), timeout / 1000000.0);
|
||||
fprintf(stderr, "%s: `%s'. Trying again in %.2f seconds...\n",
|
||||
ret == EAI_SYSTEM ? strerror(errno) : gai_strerror(ret),
|
||||
peerConfig.endpoint.c_str(), timeout / 1000000.0);
|
||||
usleep(timeout);
|
||||
}
|
||||
if ((resolved->ai_family == AF_INET && resolved->ai_addrlen == sizeof(sockaddr_in)) || (resolved->ai_family == AF_INET6 && resolved->ai_addrlen == sizeof(sockaddr_in6))) {
|
||||
if ((resolved->ai_family == AF_INET &&
|
||||
resolved->ai_addrlen == sizeof(sockaddr_in)) ||
|
||||
(resolved->ai_family == AF_INET6 &&
|
||||
resolved->ai_addrlen == sizeof(sockaddr_in6))) {
|
||||
memcpy(&endpoint, resolved->ai_addr, resolved->ai_addrlen);
|
||||
memccpy(&peerStruct->endpoint.addr, &endpoint, 0, sizeof(peerStruct->endpoint.addr));
|
||||
memccpy(&peerStruct->endpoint.addr, &endpoint, 0,
|
||||
sizeof(peerStruct->endpoint.addr));
|
||||
if (resolved->ai_family == AF_INET) {
|
||||
peerStruct->endpoint.addr4.sin_addr.s_addr = ((sockaddr_in *)&endpoint)->sin_addr.s_addr;
|
||||
peerStruct->endpoint.addr4.sin_port = ((sockaddr_in *)&endpoint)->sin_port;
|
||||
peerStruct->endpoint.addr4.sin_addr.s_addr =
|
||||
((sockaddr_in *)&endpoint)->sin_addr.s_addr;
|
||||
peerStruct->endpoint.addr4.sin_port =
|
||||
((sockaddr_in *)&endpoint)->sin_port;
|
||||
peerStruct->endpoint.addr4.sin_family = AF_INET;
|
||||
} else {
|
||||
peerStruct->endpoint.addr6.sin6_addr = ((struct sockaddr_in6 *)&endpoint)->sin6_addr;
|
||||
peerStruct->endpoint.addr6.sin6_port = ((struct sockaddr_in6 *)&endpoint)->sin6_port;
|
||||
peerStruct->endpoint.addr6.sin6_addr =
|
||||
((struct sockaddr_in6 *)&endpoint)->sin6_addr;
|
||||
peerStruct->endpoint.addr6.sin6_port =
|
||||
((struct sockaddr_in6 *)&endpoint)->sin6_port;
|
||||
peerStruct->endpoint.addr6.sin6_family = AF_INET6;
|
||||
}
|
||||
} else {
|
||||
@ -235,8 +264,10 @@ void setConfig::Execute() {
|
||||
|
||||
// Set allowed IPs
|
||||
if (peerConfig.allowedIPs.size() > 0) {
|
||||
peerStruct->flags = (wg_peer_flags)(peerStruct->flags|WGPEER_REPLACE_ALLOWEDIPS);
|
||||
for (unsigned int allowIndex = 0; allowIndex < peerConfig.allowedIPs.size(); allowIndex++) {
|
||||
peerStruct->flags =
|
||||
(wg_peer_flags)(peerStruct->flags | WGPEER_REPLACE_ALLOWEDIPS);
|
||||
for (unsigned int allowIndex = 0;
|
||||
allowIndex < peerConfig.allowedIPs.size(); allowIndex++) {
|
||||
auto ip = peerConfig.allowedIPs[allowIndex];
|
||||
unsigned long cidr = 0;
|
||||
if (ip.find("/") != std::string::npos) {
|
||||
@ -247,24 +278,29 @@ void setConfig::Execute() {
|
||||
if (strchr(ip.c_str(), ':')) {
|
||||
if (inet_pton(AF_INET6, ip.c_str(), &newAllowedIP->ip6) == 1) {
|
||||
newAllowedIP->family = AF_INET6;
|
||||
if (cidr == 0) cidr = 128;
|
||||
if (cidr == 0)
|
||||
cidr = 128;
|
||||
}
|
||||
} else {
|
||||
if (inet_pton(AF_INET, ip.c_str(), &newAllowedIP->ip4) == 1) {
|
||||
newAllowedIP->family = AF_INET;
|
||||
if (cidr == 0) cidr = 32;
|
||||
if (cidr == 0)
|
||||
cidr = 32;
|
||||
}
|
||||
}
|
||||
if (newAllowedIP->family == AF_UNSPEC || cidr <= 0) continue;
|
||||
if (newAllowedIP->family == AF_UNSPEC || cidr <= 0)
|
||||
continue;
|
||||
newAllowedIP->cidr = cidr;
|
||||
if (allowIndex > 0) newAllowedIP->next_allowedip = peerStruct->first_allowedip;
|
||||
if (allowIndex > 0)
|
||||
newAllowedIP->next_allowedip = peerStruct->first_allowedip;
|
||||
peerStruct->first_allowedip = newAllowedIP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add to Peer struct
|
||||
if (peerIndex > 0) peerStruct->next_peer = deviceStruct->first_peer;
|
||||
if (peerIndex > 0)
|
||||
peerStruct->next_peer = deviceStruct->first_peer;
|
||||
deviceStruct->first_peer = peerStruct;
|
||||
}
|
||||
|
||||
@ -272,15 +308,19 @@ void setConfig::Execute() {
|
||||
if ((res = wg_set_device(deviceStruct)) < 0) {
|
||||
std::string err = "Set wireguard config Error code: ";
|
||||
err = err.append(std::to_string(res));
|
||||
if (res == -ENODEV) err = "No such device";
|
||||
else if (res == -EINVAL) err = "Invalid argument";
|
||||
else if (res == -ENOSPC) err = "No space left on device";
|
||||
if (res == -ENODEV)
|
||||
err = "No such device";
|
||||
else if (res == -EINVAL)
|
||||
err = "Invalid argument";
|
||||
else if (res == -ENOSPC)
|
||||
err = "No space left on device";
|
||||
SetError(err);
|
||||
}
|
||||
|
||||
if (res >= 0) {
|
||||
auto res = setIps(wgName, Address);
|
||||
if (res.length() > 0) SetError(res);
|
||||
if (res.length() > 0)
|
||||
SetError(res);
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,16 +330,25 @@ const char* getHostAddress(bool addPort, const sockaddr* addr) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
int ret;
|
||||
socklen_t addr_len = 0;
|
||||
if (addr->sa_family == AF_INET) addr_len = sizeof(struct sockaddr_in);
|
||||
else if (addr->sa_family == AF_INET6) addr_len = sizeof(struct sockaddr_in6);
|
||||
if (addr->sa_family == AF_INET)
|
||||
addr_len = sizeof(struct sockaddr_in);
|
||||
else if (addr->sa_family == AF_INET6)
|
||||
addr_len = sizeof(struct sockaddr_in6);
|
||||
|
||||
ret = getnameinfo(addr, addr_len, host, sizeof(host), service, sizeof(service), NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST);
|
||||
ret =
|
||||
getnameinfo(addr, addr_len, host, sizeof(host), service, sizeof(service),
|
||||
NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST);
|
||||
if (ret) {
|
||||
strncpy(buf, gai_strerror(ret), sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
} else {
|
||||
if (addPort) snprintf(buf, sizeof(buf), (addr->sa_family == AF_INET6 && strchr(host, ':')) ? "[%s]:%s" : "%s:%s", host, service);
|
||||
else snprintf(buf, sizeof(buf), "%s", host);
|
||||
if (addPort)
|
||||
snprintf(buf, sizeof(buf),
|
||||
(addr->sa_family == AF_INET6 && strchr(host, ':')) ? "[%s]:%s"
|
||||
: "%s:%s",
|
||||
host, service);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%s", host);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
@ -311,7 +360,8 @@ std::string keyTo64(const uint8_t *key) {
|
||||
}
|
||||
|
||||
void getConfig::Execute() {
|
||||
int res; wg_device *device;
|
||||
int res;
|
||||
wg_device *device;
|
||||
if ((res = wg_get_device(&device, strdup(wgName.c_str()))) < 0) {
|
||||
std::string err = "Cannot get wireguard device, Error code ";
|
||||
err = err.append(std::to_string(res));
|
||||
@ -319,18 +369,26 @@ void getConfig::Execute() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->flags & WGDEVICE_HAS_PRIVATE_KEY) privateKey = keyTo64(device->private_key);
|
||||
if (device->flags & WGDEVICE_HAS_PUBLIC_KEY) publicKey = keyTo64(device->public_key);
|
||||
if (device->listen_port > 0) portListen = device->listen_port;
|
||||
if (device->flags & WGDEVICE_HAS_PRIVATE_KEY)
|
||||
privateKey = keyTo64(device->private_key);
|
||||
if (device->flags & WGDEVICE_HAS_PUBLIC_KEY)
|
||||
publicKey = keyTo64(device->public_key);
|
||||
if (device->listen_port > 0)
|
||||
portListen = device->listen_port;
|
||||
|
||||
// Set Address array and get interface ip addresses
|
||||
ifaddrs *ptr_ifaddrs = nullptr;
|
||||
if (getifaddrs(&ptr_ifaddrs) > 0) {
|
||||
for (ifaddrs* ptr_entry = ptr_ifaddrs; ptr_entry != nullptr; ptr_entry = ptr_entry->ifa_next) {
|
||||
if (ptr_entry->ifa_addr == nullptr) continue;
|
||||
else if (strcmp(ptr_entry->ifa_name, wgName.c_str()) != 0) continue;
|
||||
else if (ptr_entry->ifa_addr->sa_family == AF_INET) Address.push_back(getHostAddress(false, ptr_entry->ifa_addr));
|
||||
else if (ptr_entry->ifa_addr->sa_family == AF_INET6) Address.push_back(getHostAddress(false, ptr_entry->ifa_addr));
|
||||
for (ifaddrs *ptr_entry = ptr_ifaddrs; ptr_entry != nullptr;
|
||||
ptr_entry = ptr_entry->ifa_next) {
|
||||
if (ptr_entry->ifa_addr == nullptr)
|
||||
continue;
|
||||
else if (strcmp(ptr_entry->ifa_name, wgName.c_str()) != 0)
|
||||
continue;
|
||||
else if (ptr_entry->ifa_addr->sa_family == AF_INET)
|
||||
Address.push_back(getHostAddress(false, ptr_entry->ifa_addr));
|
||||
else if (ptr_entry->ifa_addr->sa_family == AF_INET6)
|
||||
Address.push_back(getHostAddress(false, ptr_entry->ifa_addr));
|
||||
}
|
||||
freeifaddrs(ptr_ifaddrs);
|
||||
}
|
||||
@ -338,20 +396,32 @@ void getConfig::Execute() {
|
||||
wg_peer *peer;
|
||||
for ((peer) = (device)->first_peer; (peer); (peer) = (peer)->next_peer) {
|
||||
auto PeerConfig = Peer();
|
||||
if (peer->flags & WGPEER_HAS_PRESHARED_KEY) PeerConfig.presharedKey = keyTo64(peer->preshared_key);
|
||||
if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL && peer->persistent_keepalive_interval > 0) PeerConfig.keepInterval = peer->persistent_keepalive_interval;
|
||||
if (peer->endpoint.addr.sa_family == AF_INET||peer->endpoint.addr.sa_family == AF_INET6) PeerConfig.endpoint = getHostAddress(true, &peer->endpoint.addr);
|
||||
if (peer->last_handshake_time.tv_sec > 0) PeerConfig.last_handshake = peer->last_handshake_time.tv_sec*1000;
|
||||
if (peer->rx_bytes > 0) PeerConfig.rxBytes = peer->rx_bytes;
|
||||
if (peer->tx_bytes > 0) PeerConfig.txBytes = peer->tx_bytes;
|
||||
if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
|
||||
PeerConfig.presharedKey = keyTo64(peer->preshared_key);
|
||||
if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL &&
|
||||
peer->persistent_keepalive_interval > 0)
|
||||
PeerConfig.keepInterval = peer->persistent_keepalive_interval;
|
||||
if (peer->endpoint.addr.sa_family == AF_INET ||
|
||||
peer->endpoint.addr.sa_family == AF_INET6)
|
||||
PeerConfig.endpoint = getHostAddress(true, &peer->endpoint.addr);
|
||||
if (peer->last_handshake_time.tv_sec > 0)
|
||||
PeerConfig.last_handshake = peer->last_handshake_time.tv_sec * 1000;
|
||||
if (peer->rx_bytes > 0)
|
||||
PeerConfig.rxBytes = peer->rx_bytes;
|
||||
if (peer->tx_bytes > 0)
|
||||
PeerConfig.txBytes = peer->tx_bytes;
|
||||
if (peer->first_allowedip) {
|
||||
wg_allowedip *allowedip;
|
||||
for ((allowedip) = (peer)->first_allowedip; (allowedip); (allowedip) = (allowedip)->next_allowedip) {
|
||||
for ((allowedip) = (peer)->first_allowedip; (allowedip);
|
||||
(allowedip) = (allowedip)->next_allowedip) {
|
||||
static char buf[INET6_ADDRSTRLEN + 1];
|
||||
memset(buf, 0, INET6_ADDRSTRLEN + 1);
|
||||
if (allowedip->family == AF_INET) inet_ntop(AF_INET, &allowedip->ip4, buf, INET6_ADDRSTRLEN);
|
||||
else if (allowedip->family == AF_INET6) inet_ntop(AF_INET6, &allowedip->ip6, buf, INET6_ADDRSTRLEN);
|
||||
snprintf(buf + strlen(buf), INET6_ADDRSTRLEN - strlen(buf), "/%d", allowedip->cidr);
|
||||
if (allowedip->family == AF_INET)
|
||||
inet_ntop(AF_INET, &allowedip->ip4, buf, INET6_ADDRSTRLEN);
|
||||
else if (allowedip->family == AF_INET6)
|
||||
inet_ntop(AF_INET6, &allowedip->ip6, buf, INET6_ADDRSTRLEN);
|
||||
snprintf(buf + strlen(buf), INET6_ADDRSTRLEN - strlen(buf), "/%d",
|
||||
allowedip->cidr);
|
||||
PeerConfig.allowedIPs.push_back(buf);
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,47 @@
|
||||
#include <napi.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <wireguard-nt/include/wireguard.h>
|
||||
#include <win/shared.cpp>
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include "wginterface.hh"
|
||||
#include <accctrl.h>
|
||||
#include <aclapi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <bcrypt.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <cstdlib>
|
||||
#include <devguid.h>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include <iphlpapi.h>
|
||||
#include <map>
|
||||
#include <napi.h>
|
||||
#include <ndisguid.h>
|
||||
#include <setupapi.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <sysinfoapi.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <vector>
|
||||
#include <wgkeys.hh>
|
||||
#include <win/shared.cpp>
|
||||
#include <wincrypt.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <winternl.h>
|
||||
#include <wireguard-nt/include/wireguard.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <bcrypt.h>
|
||||
#include <wincrypt.h>
|
||||
#include <sysinfoapi.h>
|
||||
#include <winternl.h>
|
||||
#include <cstdlib>
|
||||
#include <setupapi.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <devguid.h>
|
||||
#include <ndisguid.h>
|
||||
#include "wginterface.hh"
|
||||
#include <wgkeys.hh>
|
||||
|
||||
const DEVPROPKEY devpkey_name = { { 0x65726957, 0x7547, 0x7261, { 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x4b, 0x65, 0x79 } }, DEVPROPID_FIRST_USABLE + 1 };
|
||||
const DEVPROPKEY devpkey_name = {
|
||||
{0x65726957,
|
||||
0x7547,
|
||||
0x7261,
|
||||
{0x64, 0x4e, 0x61, 0x6d, 0x65, 0x4b, 0x65, 0x79}},
|
||||
DEVPROPID_FIRST_USABLE + 1};
|
||||
#define IFNAMSIZ MAX_ADAPTER_NAME - 1
|
||||
|
||||
static WIREGUARD_CREATE_ADAPTER_FUNC *WireGuardCreateAdapter;
|
||||
static WIREGUARD_OPEN_ADAPTER_FUNC *WireGuardOpenAdapter;
|
||||
static WIREGUARD_CLOSE_ADAPTER_FUNC *WireGuardCloseAdapter;
|
||||
static WIREGUARD_GET_ADAPTER_LUID_FUNC *WireGuardGetAdapterLUID;
|
||||
static WIREGUARD_GET_RUNNING_DRIVER_VERSION_FUNC *WireGuardGetRunningDriverVersion;
|
||||
static WIREGUARD_GET_RUNNING_DRIVER_VERSION_FUNC
|
||||
*WireGuardGetRunningDriverVersion;
|
||||
static WIREGUARD_DELETE_DRIVER_FUNC *WireGuardDeleteDriver;
|
||||
static WIREGUARD_SET_LOGGER_FUNC *WireGuardSetLogger;
|
||||
static WIREGUARD_SET_ADAPTER_LOGGING_FUNC *WireGuardSetAdapterLogging;
|
||||
@ -44,55 +50,84 @@ static WIREGUARD_SET_ADAPTER_STATE_FUNC *WireGuardSetAdapterState;
|
||||
static WIREGUARD_GET_CONFIGURATION_FUNC *WireGuardGetConfiguration;
|
||||
static WIREGUARD_SET_CONFIGURATION_FUNC *WireGuardSetConfiguration;
|
||||
|
||||
unsigned long maxName() {
|
||||
return IFNAMSIZ;
|
||||
}
|
||||
unsigned long maxName() { return IFNAMSIZ; }
|
||||
|
||||
std::string getErrorString(DWORD errorMessageID) {
|
||||
if (errorMessageID == 0 || errorMessageID < 0) std::string("Error code: ").append(std::to_string(errorMessageID));
|
||||
if (errorMessageID == 0 || errorMessageID < 0)
|
||||
std::string("Error code: ").append(std::to_string(errorMessageID));
|
||||
LPSTR messageBuffer = nullptr;
|
||||
// Ask Win32 to give us the string version of that message ID.
|
||||
//The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message string will be).
|
||||
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
||||
// The parameters we pass in, tell Win32 to create the buffer that holds the
|
||||
// message for us (because we don't yet know how long the message string will
|
||||
// be).
|
||||
size_t size = FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&messageBuffer, 0, NULL);
|
||||
// Copy the error message into a std::string.
|
||||
std::string message(messageBuffer, size);
|
||||
// Free the Win32's string's buffer.
|
||||
LocalFree(messageBuffer);
|
||||
return std::string("Error code: ").append(std::to_string(errorMessageID)).append(", Message: ").append(message);
|
||||
return std::string("Error code: ")
|
||||
.append(std::to_string(errorMessageID))
|
||||
.append(", Message: ")
|
||||
.append(message);
|
||||
}
|
||||
|
||||
std::string startAddon(const Napi::Env env) {
|
||||
if (!IsRunAsAdmin()) return "Run nodejs with administrator privilegies";
|
||||
if (!IsRunAsAdmin())
|
||||
return "Run nodejs with administrator privilegies";
|
||||
auto DLLPATH = env.Global().ToObject().Get("WIREGUARD_DLL_PATH");
|
||||
if (!(DLLPATH.IsString())) return "Require WIREGUARD_DLL_PATH in Global process";
|
||||
if (!(DLLPATH.IsString()))
|
||||
return "Require WIREGUARD_DLL_PATH in Global process";
|
||||
LPCWSTR dllPath = toLpcwstr(DLLPATH.ToString());
|
||||
|
||||
HMODULE WireGuardDll = LoadLibraryExW(dllPath, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!WireGuardDll) return ((std::string)"Failed to initialize WireGuardNT, ").append(getErrorString(GetLastError()));;
|
||||
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(WireGuardDll, #Name)) == NULL)
|
||||
if (X(WireGuardCreateAdapter) || X(WireGuardOpenAdapter) || X(WireGuardCloseAdapter) || X(WireGuardGetAdapterLUID) || X(WireGuardGetRunningDriverVersion) || X(WireGuardDeleteDriver) || X(WireGuardSetLogger) || X(WireGuardSetAdapterLogging) || X(WireGuardGetAdapterState) || X(WireGuardSetAdapterState) || X(WireGuardGetConfiguration) || X(WireGuardSetConfiguration))
|
||||
HMODULE WireGuardDll = LoadLibraryExW(dllPath, NULL,
|
||||
LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!WireGuardDll)
|
||||
return ((std::string) "Failed to initialize WireGuardNT, ")
|
||||
.append(getErrorString(GetLastError()));
|
||||
;
|
||||
#define X(Name) \
|
||||
((*(FARPROC *)&Name = GetProcAddress(WireGuardDll, #Name)) == NULL)
|
||||
if (X(WireGuardCreateAdapter) || X(WireGuardOpenAdapter) ||
|
||||
X(WireGuardCloseAdapter) || X(WireGuardGetAdapterLUID) ||
|
||||
X(WireGuardGetRunningDriverVersion) || X(WireGuardDeleteDriver) ||
|
||||
X(WireGuardSetLogger) || X(WireGuardSetAdapterLogging) ||
|
||||
X(WireGuardGetAdapterState) || X(WireGuardSetAdapterState) ||
|
||||
X(WireGuardGetConfiguration) || X(WireGuardSetConfiguration))
|
||||
#undef X
|
||||
{
|
||||
DWORD LastError = GetLastError();
|
||||
FreeLibrary(WireGuardDll);
|
||||
SetLastError(LastError);
|
||||
return ((std::string)"Failed to set Functions from WireGuardNT DLL, ").append(getErrorString(GetLastError()));;
|
||||
return ((std::string) "Failed to set Functions from WireGuardNT DLL, ")
|
||||
.append(getErrorString(GetLastError()));
|
||||
;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string versionDrive() {
|
||||
WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardCreateAdapter(L"getWgVersion", L"Wireguard-tools.js", NULL);
|
||||
WIREGUARD_ADAPTER_HANDLE Adapter =
|
||||
WireGuardCreateAdapter(L"getWgVersion", L"Wireguard-tools.js", NULL);
|
||||
DWORD Version = WireGuardGetRunningDriverVersion();
|
||||
if (Version == 0) {
|
||||
auto statusErr = GetLastError();
|
||||
WireGuardCloseAdapter(Adapter);
|
||||
if (statusErr == ERROR_FILE_NOT_FOUND) return "Driver not loaded";
|
||||
return ((std::string)"Cannot get version drive, ").append(getErrorString(GetLastError()));
|
||||
if (statusErr == ERROR_FILE_NOT_FOUND)
|
||||
return "Driver not loaded";
|
||||
return ((std::string) "Cannot get version drive, ")
|
||||
.append(getErrorString(GetLastError()));
|
||||
}
|
||||
WireGuardCloseAdapter(Adapter);
|
||||
return ((std::string)"WireGuardNT v").append(std::to_string((Version >> 16) & 0xff)).append(".").append(std::to_string((Version >> 0) & 0xff));
|
||||
return ((std::string) "WireGuardNT v")
|
||||
.append(std::to_string((Version >> 16) & 0xff))
|
||||
.append(".")
|
||||
.append(std::to_string((Version >> 0) & 0xff));
|
||||
}
|
||||
|
||||
void listDevices::Execute() {
|
||||
@ -105,23 +140,30 @@ void listDevices::Execute() {
|
||||
for (auto &preit : arrayPrefix) {
|
||||
int ret = 0;
|
||||
find_handle = FindFirstFile("\\\\.\\pipe\\*", &find_data);
|
||||
if (find_handle == INVALID_HANDLE_VALUE) continue;
|
||||
if (find_handle == INVALID_HANDLE_VALUE)
|
||||
continue;
|
||||
|
||||
char *iface;
|
||||
do {
|
||||
if (strncmp(preit.c_str(), find_data.cFileName, strlen(preit.c_str()))) continue;
|
||||
if (strncmp(preit.c_str(), find_data.cFileName, strlen(preit.c_str())))
|
||||
continue;
|
||||
iface = find_data.cFileName + strlen(preit.c_str());
|
||||
listInfo setInfo;
|
||||
setInfo.tunType = "userspace";
|
||||
setInfo.pathSock = std::string("\\\\.\\pipe\\").append(preit).append(iface);
|
||||
setInfo.pathSock =
|
||||
std::string("\\\\.\\pipe\\").append(preit).append(iface);
|
||||
deviceNames[std::string(iface)] = setInfo;
|
||||
} while (FindNextFile(find_handle, &find_data));
|
||||
FindClose(find_handle);
|
||||
if (ret < 0) return SetError(std::string("Erro code: ").append(std::to_string(ret)));
|
||||
if (ret < 0)
|
||||
return SetError(std::string("Erro code: ").append(std::to_string(ret)));
|
||||
}
|
||||
|
||||
HDEVINFO dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL);
|
||||
if (dev_info == INVALID_HANDLE_VALUE) return SetError("Cannot get devices");
|
||||
HDEVINFO dev_info =
|
||||
SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, L"SWD\\WireGuard", NULL,
|
||||
DIGCF_PRESENT, NULL, NULL, NULL);
|
||||
if (dev_info == INVALID_HANDLE_VALUE)
|
||||
return SetError("Cannot get devices");
|
||||
|
||||
for (DWORD i = 0;; ++i) {
|
||||
DWORD buf_len;
|
||||
@ -133,24 +175,37 @@ void listDevices::Execute() {
|
||||
char *interface_name;
|
||||
|
||||
if (!SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data)) {
|
||||
if (GetLastError() == ERROR_NO_MORE_ITEMS) break;
|
||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name, &prop_type, (PBYTE)adapter_name, sizeof(adapter_name), NULL, 0) || prop_type != DEVPROP_TYPE_STRING) continue;
|
||||
if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name,
|
||||
&prop_type, (PBYTE)adapter_name,
|
||||
sizeof(adapter_name), NULL, 0) ||
|
||||
prop_type != DEVPROP_TYPE_STRING)
|
||||
continue;
|
||||
adapter_name[_countof(adapter_name) - 1] = L'0';
|
||||
if (!adapter_name[0]) continue;
|
||||
buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, NULL, 0, NULL, NULL);
|
||||
if (!buf_len) continue;
|
||||
if (!adapter_name[0])
|
||||
continue;
|
||||
buf_len =
|
||||
WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, NULL, 0, NULL, NULL);
|
||||
if (!buf_len)
|
||||
continue;
|
||||
interface_name = (char *)malloc(buf_len);
|
||||
if (!interface_name) continue;
|
||||
buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, interface_name, buf_len, NULL, NULL);
|
||||
if (!interface_name)
|
||||
continue;
|
||||
buf_len = WideCharToMultiByte(CP_UTF8, 0, adapter_name, -1, interface_name,
|
||||
buf_len, NULL, NULL);
|
||||
if (!buf_len) {
|
||||
free(interface_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CM_Get_DevNode_Status(&status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS && (status & (DN_DRIVER_LOADED | DN_STARTED)) == (DN_DRIVER_LOADED | DN_STARTED)) {
|
||||
if (CM_Get_DevNode_Status(&status, &problem_code, dev_info_data.DevInst,
|
||||
0) == CR_SUCCESS &&
|
||||
(status & (DN_DRIVER_LOADED | DN_STARTED)) ==
|
||||
(DN_DRIVER_LOADED | DN_STARTED)) {
|
||||
listInfo setInfo;
|
||||
setInfo.tunType = "kernel";
|
||||
deviceNames[std::string(interface_name)] = setInfo;
|
||||
@ -162,8 +217,12 @@ void listDevices::Execute() {
|
||||
|
||||
void deleteInterface::Execute() {
|
||||
WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(wgName));
|
||||
if (!Adapter) return SetError("This interface not exists in Wireguard-Tools.js addon!");
|
||||
if (!(WireGuardSetAdapterState(Adapter, WIREGUARD_ADAPTER_STATE::WIREGUARD_ADAPTER_STATE_DOWN))) return SetError(std::string("Failed to set down interface, ").append(getErrorString(GetLastError())));
|
||||
if (!Adapter)
|
||||
return SetError("This interface not exists in Wireguard-Tools.js addon!");
|
||||
if (!(WireGuardSetAdapterState(
|
||||
Adapter, WIREGUARD_ADAPTER_STATE::WIREGUARD_ADAPTER_STATE_DOWN)))
|
||||
return SetError(std::string("Failed to set down interface, ")
|
||||
.append(getErrorString(GetLastError())));
|
||||
WireGuardCloseAdapter(Adapter);
|
||||
}
|
||||
|
||||
@ -174,18 +233,21 @@ void deleteInterface::Execute() {
|
||||
* C: From
|
||||
*/
|
||||
template <typename T, typename C> C *changePoint(T *x) {
|
||||
// reinterpret_cast<WIREGUARD_ALLOWED_IP*>(((char*)x) + sizeof(WIREGUARD_PEER));
|
||||
// std::cout << "Sizeof: " << sizeof(C) << ", " << typeid(T).name() << " -> " << typeid(C).name() << std::endl;
|
||||
// reinterpret_cast<WIREGUARD_ALLOWED_IP*>(((char*)x) +
|
||||
// sizeof(WIREGUARD_PEER)); std::cout << "Sizeof: " << sizeof(C) << ", " <<
|
||||
// typeid(T).name() << " -> " << typeid(C).name() << std::endl;
|
||||
return reinterpret_cast<C *>(((char *)x) + sizeof(T));
|
||||
}
|
||||
|
||||
void getConfig::Execute() {
|
||||
WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(wgName));
|
||||
if (!Adapter) return SetError("This interface not exists in Wireguard-Tools.js addon!");
|
||||
if (!Adapter)
|
||||
return SetError("This interface not exists in Wireguard-Tools.js addon!");
|
||||
NET_LUID InterfaceLuid;
|
||||
WireGuardGetAdapterLUID(Adapter, &InterfaceLuid);
|
||||
try {
|
||||
for (auto aip : getIpAddr(InterfaceLuid)) Address.push_back(aip);
|
||||
for (auto aip : getIpAddr(InterfaceLuid))
|
||||
Address.push_back(aip);
|
||||
} catch (std::string err) {
|
||||
return SetError(err);
|
||||
}
|
||||
@ -195,18 +257,28 @@ void getConfig::Execute() {
|
||||
|
||||
while (!(WireGuardGetConfiguration(Adapter, wg_iface, &buf_len))) {
|
||||
free(wg_iface);
|
||||
if (GetLastError() != ERROR_MORE_DATA) return SetError((std::string("Failed get interface config, code: ")).append(std::to_string(GetLastError())));
|
||||
if (GetLastError() != ERROR_MORE_DATA)
|
||||
return SetError((std::string("Failed get interface config, code: "))
|
||||
.append(std::to_string(GetLastError())));
|
||||
wg_iface = (WIREGUARD_INTERFACE *)malloc(buf_len);
|
||||
if (!wg_iface) return SetError(((std::string)"Failed get interface config, ").append(std::to_string(-errno)));
|
||||
if (!wg_iface)
|
||||
return SetError(((std::string) "Failed get interface config, ")
|
||||
.append(std::to_string(-errno)));
|
||||
}
|
||||
|
||||
if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY) privateKey = wgKeys::toString(wg_iface->PrivateKey);
|
||||
if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PUBLIC_KEY) publicKey = wgKeys::toString(wg_iface->PublicKey);
|
||||
if (wg_iface->Flags &
|
||||
WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY)
|
||||
privateKey = wgKeys::toString(wg_iface->PrivateKey);
|
||||
if (wg_iface->Flags &
|
||||
WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PUBLIC_KEY)
|
||||
publicKey = wgKeys::toString(wg_iface->PublicKey);
|
||||
portListen = 0;
|
||||
if (wg_iface->Flags & WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_LISTEN_PORT) portListen = wg_iface->ListenPort;
|
||||
if (wg_iface->Flags &
|
||||
WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_LISTEN_PORT)
|
||||
portListen = wg_iface->ListenPort;
|
||||
|
||||
|
||||
WIREGUARD_PEER *wg_peer = changePoint<WIREGUARD_INTERFACE, WIREGUARD_PEER>(wg_iface);
|
||||
WIREGUARD_PEER *wg_peer =
|
||||
changePoint<WIREGUARD_INTERFACE, WIREGUARD_PEER>(wg_iface);
|
||||
for (DWORD i = 0; i < wg_iface->PeersCount; i++) {
|
||||
auto pubKey = wgKeys::toString(wg_peer->PublicKey);
|
||||
Peer peerConfig;
|
||||
@ -214,20 +286,29 @@ void getConfig::Execute() {
|
||||
peerConfig.txBytes = wg_peer->TxBytes;
|
||||
peerConfig.rxBytes = wg_peer->RxBytes;
|
||||
|
||||
if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PRESHARED_KEY) peerConfig.presharedKey = wgKeys::toString(wg_peer->PresharedKey);
|
||||
if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT) peerConfig.endpoint = parseEndpoint(&wg_peer->Endpoint);
|
||||
if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE) peerConfig.keepInterval = wg_peer->PersistentKeepalive;
|
||||
if (wg_peer->LastHandshake > 0) peerConfig.last_handshake = (wg_peer->LastHandshake / 10000000 - 11644473600LL) * 1000;
|
||||
if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PRESHARED_KEY)
|
||||
peerConfig.presharedKey = wgKeys::toString(wg_peer->PresharedKey);
|
||||
if (wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT)
|
||||
peerConfig.endpoint = parseEndpoint(&wg_peer->Endpoint);
|
||||
if (wg_peer->Flags &
|
||||
WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE)
|
||||
peerConfig.keepInterval = wg_peer->PersistentKeepalive;
|
||||
if (wg_peer->LastHandshake > 0)
|
||||
peerConfig.last_handshake =
|
||||
(wg_peer->LastHandshake / 10000000 - 11644473600LL) * 1000;
|
||||
|
||||
WIREGUARD_ALLOWED_IP* wg_aip = changePoint<WIREGUARD_PEER, WIREGUARD_ALLOWED_IP>(wg_peer);
|
||||
WIREGUARD_ALLOWED_IP *wg_aip =
|
||||
changePoint<WIREGUARD_PEER, WIREGUARD_ALLOWED_IP>(wg_peer);
|
||||
for (DWORD __aip = 0; __aip < wg_peer->AllowedIPsCount; __aip++) {
|
||||
char saddr[INET6_ADDRSTRLEN];
|
||||
if (wg_aip->AddressFamily == AF_INET) {
|
||||
inet_ntop(AF_INET, &wg_aip->Address.V6, saddr, INET_ADDRSTRLEN);
|
||||
peerConfig.allowedIPs.push_back(std::string(saddr).append("/").append(std::to_string(wg_aip->Cidr)));
|
||||
peerConfig.allowedIPs.push_back(std::string(saddr).append("/").append(
|
||||
std::to_string(wg_aip->Cidr)));
|
||||
} else if (wg_aip->AddressFamily == AF_INET6) {
|
||||
inet_ntop(AF_INET6, &wg_aip->Address.V6, saddr, INET6_ADDRSTRLEN);
|
||||
peerConfig.allowedIPs.push_back(std::string(saddr).append("/").append(std::to_string(wg_aip->Cidr)));
|
||||
peerConfig.allowedIPs.push_back(std::string(saddr).append("/").append(
|
||||
std::to_string(wg_aip->Cidr)));
|
||||
}
|
||||
++wg_aip;
|
||||
}
|
||||
@ -241,29 +322,44 @@ void getConfig::Execute() {
|
||||
void setConfig::Execute() {
|
||||
DWORD buf_len = sizeof(WIREGUARD_INTERFACE);
|
||||
for (auto peer : peersVector) {
|
||||
if (DWORD_MAX - buf_len < sizeof(WIREGUARD_PEER)) return SetError("Buffer overflow");
|
||||
if (DWORD_MAX - buf_len < sizeof(WIREGUARD_PEER))
|
||||
return SetError("Buffer overflow");
|
||||
buf_len += sizeof(WIREGUARD_PEER);
|
||||
for (auto aip : peer.second.allowedIPs) {
|
||||
if (DWORD_MAX - buf_len < sizeof(WIREGUARD_ALLOWED_IP)) return SetError("Buffer overflow");
|
||||
if (DWORD_MAX - buf_len < sizeof(WIREGUARD_ALLOWED_IP))
|
||||
return SetError("Buffer overflow");
|
||||
buf_len += sizeof(WIREGUARD_ALLOWED_IP);
|
||||
}
|
||||
}
|
||||
WIREGUARD_INTERFACE *wg_iface = reinterpret_cast<WIREGUARD_INTERFACE*>(calloc(1, buf_len));
|
||||
if (!wg_iface) return SetError("Cannot alloc buff");
|
||||
WIREGUARD_INTERFACE *wg_iface =
|
||||
reinterpret_cast<WIREGUARD_INTERFACE *>(calloc(1, buf_len));
|
||||
if (!wg_iface)
|
||||
return SetError("Cannot alloc buff");
|
||||
wg_iface->PeersCount = 0;
|
||||
|
||||
wgKeys::stringToKey(wg_iface->PrivateKey, privateKey);
|
||||
wg_iface->Flags = WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY;
|
||||
wg_iface->Flags =
|
||||
WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_PRIVATE_KEY;
|
||||
|
||||
wg_iface->ListenPort = portListen;
|
||||
if (portListen >= 0 && 65535 <= portListen) wg_iface->Flags = (WIREGUARD_INTERFACE_FLAG)(wg_iface->Flags|WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_HAS_LISTEN_PORT);
|
||||
if (portListen >= 0 && 65535 <= portListen)
|
||||
wg_iface->Flags =
|
||||
(WIREGUARD_INTERFACE_FLAG)(wg_iface->Flags |
|
||||
WIREGUARD_INTERFACE_FLAG::
|
||||
WIREGUARD_INTERFACE_HAS_LISTEN_PORT);
|
||||
|
||||
if (replacePeers) wg_iface->Flags = (WIREGUARD_INTERFACE_FLAG)(wg_iface->Flags|WIREGUARD_INTERFACE_FLAG::WIREGUARD_INTERFACE_REPLACE_PEERS);
|
||||
if (replacePeers)
|
||||
wg_iface->Flags =
|
||||
(WIREGUARD_INTERFACE_FLAG)(wg_iface->Flags |
|
||||
WIREGUARD_INTERFACE_FLAG::
|
||||
WIREGUARD_INTERFACE_REPLACE_PEERS);
|
||||
|
||||
WIREGUARD_ALLOWED_IP *wg_aip;
|
||||
WIREGUARD_PEER *wg_peer = changePoint<WIREGUARD_INTERFACE, WIREGUARD_PEER>(wg_iface);
|
||||
WIREGUARD_PEER *wg_peer =
|
||||
changePoint<WIREGUARD_INTERFACE, WIREGUARD_PEER>(wg_iface);
|
||||
for (auto __peer : peersVector) {
|
||||
auto peerPublicKey = __peer.first; auto peerConfig = __peer.second;
|
||||
auto peerPublicKey = __peer.first;
|
||||
auto peerConfig = __peer.second;
|
||||
try {
|
||||
wgKeys::stringToKey(wg_peer->PublicKey, peerPublicKey);
|
||||
} catch (std::string &err) {
|
||||
@ -275,13 +371,18 @@ void setConfig::Execute() {
|
||||
wg_iface->PeersCount++;
|
||||
|
||||
if (peerConfig.removeMe) {
|
||||
wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_REMOVE);
|
||||
wg_peer->Flags =
|
||||
(WIREGUARD_PEER_FLAG)(wg_peer->Flags |
|
||||
WIREGUARD_PEER_FLAG::WIREGUARD_PEER_REMOVE);
|
||||
wg_peer = changePoint<WIREGUARD_PEER, WIREGUARD_PEER>(wg_peer);
|
||||
} else {
|
||||
if (peerConfig.presharedKey.size() == B64_WG_KEY_LENGTH) {
|
||||
try {
|
||||
wgKeys::stringToKey(wg_peer->PresharedKey, peerConfig.presharedKey);
|
||||
wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PRESHARED_KEY);
|
||||
wg_peer->Flags =
|
||||
(WIREGUARD_PEER_FLAG)(wg_peer->Flags |
|
||||
WIREGUARD_PEER_FLAG::
|
||||
WIREGUARD_PEER_HAS_PRESHARED_KEY);
|
||||
} catch (std::string &err) {
|
||||
SetError(err);
|
||||
goto outEnd;
|
||||
@ -289,12 +390,19 @@ void setConfig::Execute() {
|
||||
}
|
||||
|
||||
wg_peer->PersistentKeepalive = peerConfig.keepInterval;
|
||||
if (peerConfig.keepInterval >= 0) wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE);
|
||||
if (peerConfig.keepInterval >= 0)
|
||||
wg_peer->Flags =
|
||||
(WIREGUARD_PEER_FLAG)(wg_peer->Flags |
|
||||
WIREGUARD_PEER_FLAG::
|
||||
WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE);
|
||||
|
||||
if (peerConfig.endpoint.size() > 0) {
|
||||
try {
|
||||
insertEndpoint(&wg_peer->Endpoint, peerConfig.endpoint.c_str());
|
||||
wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_HAS_ENDPOINT);
|
||||
wg_peer->Flags =
|
||||
(WIREGUARD_PEER_FLAG)(wg_peer->Flags |
|
||||
WIREGUARD_PEER_FLAG::
|
||||
WIREGUARD_PEER_HAS_ENDPOINT);
|
||||
} catch (std::string &err) {
|
||||
SetError(std::string("Cannot parse endpoint, ").append(err));
|
||||
goto outEnd;
|
||||
@ -310,29 +418,51 @@ void setConfig::Execute() {
|
||||
}
|
||||
aip = aip.substr(0, aip.find("/"));
|
||||
wg_aip->AddressFamily = strchr(aip.c_str(), ':') ? AF_INET6 : AF_INET;
|
||||
auto status = wg_aip->AddressFamily == AF_INET6 ? inet_pton(wg_aip->AddressFamily, aip.c_str(), &wg_aip->Address.V6) : inet_pton(wg_aip->AddressFamily, aip.c_str(), &wg_aip->Address.V4);
|
||||
auto status = wg_aip->AddressFamily == AF_INET6
|
||||
? inet_pton(wg_aip->AddressFamily, aip.c_str(),
|
||||
&wg_aip->Address.V6)
|
||||
: inet_pton(wg_aip->AddressFamily, aip.c_str(),
|
||||
&wg_aip->Address.V4);
|
||||
if (status == 1) {
|
||||
if (cidr == 0) cidr = wg_aip->AddressFamily == AF_INET6 ? 128 : 32;
|
||||
} else continue;
|
||||
if (cidr == 0)
|
||||
cidr = wg_aip->AddressFamily == AF_INET6 ? 128 : 32;
|
||||
} else
|
||||
continue;
|
||||
wg_aip->Cidr = cidr;
|
||||
wg_peer->AllowedIPsCount++;
|
||||
wg_aip = changePoint<WIREGUARD_ALLOWED_IP, WIREGUARD_ALLOWED_IP>(wg_aip);
|
||||
if (!(wg_peer->Flags & WIREGUARD_PEER_FLAG::WIREGUARD_PEER_REPLACE_ALLOWED_IPS)) wg_peer->Flags = (WIREGUARD_PEER_FLAG)(wg_peer->Flags|WIREGUARD_PEER_FLAG::WIREGUARD_PEER_REPLACE_ALLOWED_IPS);
|
||||
wg_aip =
|
||||
changePoint<WIREGUARD_ALLOWED_IP, WIREGUARD_ALLOWED_IP>(wg_aip);
|
||||
if (!(wg_peer->Flags &
|
||||
WIREGUARD_PEER_FLAG::WIREGUARD_PEER_REPLACE_ALLOWED_IPS))
|
||||
wg_peer->Flags =
|
||||
(WIREGUARD_PEER_FLAG)(wg_peer->Flags |
|
||||
WIREGUARD_PEER_FLAG::
|
||||
WIREGUARD_PEER_REPLACE_ALLOWED_IPS);
|
||||
}
|
||||
wg_peer = reinterpret_cast<WIREGUARD_PEER *>(((char *)wg_aip));
|
||||
}
|
||||
}
|
||||
|
||||
WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(toLpcwstr(wgName));
|
||||
if (!Adapter) Adapter = WireGuardCreateAdapter(toLpcwstr(wgName), L"Wireguard-tools.js", NULL);
|
||||
if (!Adapter) SetError(((std::string)"Failed to create adapter, ").append(getErrorString(GetLastError())));
|
||||
else if (!WireGuardSetConfiguration(Adapter, reinterpret_cast<WIREGUARD_INTERFACE*>(wg_iface), buf_len)) {
|
||||
if (!Adapter)
|
||||
Adapter =
|
||||
WireGuardCreateAdapter(toLpcwstr(wgName), L"Wireguard-tools.js", NULL);
|
||||
if (!Adapter)
|
||||
SetError(((std::string) "Failed to create adapter, ")
|
||||
.append(getErrorString(GetLastError())));
|
||||
else if (!WireGuardSetConfiguration(
|
||||
Adapter, reinterpret_cast<WIREGUARD_INTERFACE *>(wg_iface),
|
||||
buf_len)) {
|
||||
auto status = GetLastError();
|
||||
SetError(std::string("Failed to set interface config, ").append(getErrorString(status)));
|
||||
SetError(std::string("Failed to set interface config, ")
|
||||
.append(getErrorString(status)));
|
||||
WireGuardCloseAdapter(Adapter);
|
||||
} else if (!WireGuardSetAdapterState(Adapter, WIREGUARD_ADAPTER_STATE::WIREGUARD_ADAPTER_STATE_UP)) {
|
||||
} else if (!WireGuardSetAdapterState(
|
||||
Adapter,
|
||||
WIREGUARD_ADAPTER_STATE::WIREGUARD_ADAPTER_STATE_UP)) {
|
||||
auto status = GetLastError();
|
||||
SetError(std::string("Failed to set interface up, ").append(getErrorString(status)));
|
||||
SetError(std::string("Failed to set interface up, ")
|
||||
.append(getErrorString(status)));
|
||||
WireGuardCloseAdapter(Adapter);
|
||||
} else {
|
||||
if (Address.size() > 0) {
|
||||
@ -341,11 +471,19 @@ void setConfig::Execute() {
|
||||
aip = aip.substr(0, aip.find("/"));
|
||||
auto family = strchr(aip.c_str(), ':') ? AF_INET6 : AF_INET;
|
||||
SOCKADDR_INET address;
|
||||
int status = family == AF_INET ? inet_pton(family, aip.c_str(), &address.Ipv4.sin_addr) : inet_pton(family, aip.c_str(), &address.Ipv6.sin6_addr);
|
||||
if (status != 1) continue;
|
||||
int status =
|
||||
family == AF_INET
|
||||
? inet_pton(family, aip.c_str(), &address.Ipv4.sin_addr)
|
||||
: inet_pton(family, aip.c_str(), &address.Ipv6.sin6_addr);
|
||||
if (status != 1)
|
||||
continue;
|
||||
char saddr[INET6_ADDRSTRLEN];
|
||||
family == AF_INET ? inet_ntop(AF_INET, &address.Ipv4.sin_addr, saddr, INET_ADDRSTRLEN) : inet_ntop(AF_INET6, &address.Ipv6.sin6_addr, saddr, INET6_ADDRSTRLEN);
|
||||
if (family == AF_INET) IPv4 = std::string(saddr);
|
||||
family == AF_INET
|
||||
? inet_ntop(AF_INET, &address.Ipv4.sin_addr, saddr, INET_ADDRSTRLEN)
|
||||
: inet_ntop(AF_INET6, &address.Ipv6.sin6_addr, saddr,
|
||||
INET6_ADDRSTRLEN);
|
||||
if (family == AF_INET)
|
||||
IPv4 = std::string(saddr);
|
||||
// else IPv6 = std::string(saddr);
|
||||
}
|
||||
|
||||
@ -353,7 +491,8 @@ void setConfig::Execute() {
|
||||
NET_LUID InterfaceLuid;
|
||||
WireGuardGetAdapterLUID(Adapter, &InterfaceLuid);
|
||||
auto setStatus = insertIpAddr(InterfaceLuid, IPv4, IPv6);
|
||||
if (setStatus.size() > 0) SetError(setStatus);
|
||||
if (setStatus.size() > 0)
|
||||
SetError(setStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <napi.h>
|
||||
#include <iostream>
|
||||
#include "wginterface.hh"
|
||||
#include <iostream>
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Object Init(Napi::Env initEnv, Napi::Object exports) {
|
||||
/// Call Addon
|
||||
@ -24,24 +24,31 @@ Napi::Object Init(Napi::Env initEnv, Napi::Object exports) {
|
||||
|
||||
// Function's
|
||||
#ifdef SETCONFIG
|
||||
exports.Set("setConfig", Napi::Function::New(initEnv, [&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
exports.Set(
|
||||
"setConfig",
|
||||
Napi::Function::New(
|
||||
initEnv, [&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
const Napi::Env env = info.Env();
|
||||
const auto wgName = info[0];
|
||||
const auto wgConfig = info[1];
|
||||
Napi::Value ret = env.Undefined();
|
||||
if (!(wgName.IsString())) {
|
||||
Napi::Error::New(env, "Require wireguard interface name").ThrowAsJavaScriptException();
|
||||
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();
|
||||
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();
|
||||
Napi::Error::New(env, "Require wireguard config object")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
try {
|
||||
auto worker = new setConfig(env, wgName.ToString().Utf8Value(), wgConfig.ToObject());
|
||||
auto worker = new setConfig(env, wgName.ToString().Utf8Value(),
|
||||
wgConfig.ToObject());
|
||||
worker->Queue();
|
||||
return worker->setPromise.Promise();
|
||||
} catch (const Napi::Error &err) {
|
||||
@ -52,32 +59,43 @@ Napi::Object Init(Napi::Env initEnv, Napi::Object exports) {
|
||||
#endif
|
||||
|
||||
#ifdef DELIFACE
|
||||
exports.Set("deleteInterface", Napi::Function::New(initEnv, [&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
exports.Set("deleteInterface",
|
||||
Napi::Function::New(
|
||||
initEnv, [&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
const Napi::Env env = info.Env();
|
||||
const auto wgName = info[0];
|
||||
if (!(wgName.IsString())) {
|
||||
Napi::Error::New(env, "Require wireguard interface name").ThrowAsJavaScriptException();
|
||||
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();
|
||||
} else if (wgName.ToString().Utf8Value().length() >=
|
||||
maxName()) {
|
||||
Napi::Error::New(env, "interface name is so long")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
auto worker = new deleteInterface(env, wgName.ToString().Utf8Value());
|
||||
auto worker =
|
||||
new deleteInterface(env, wgName.ToString().Utf8Value());
|
||||
worker->Queue();
|
||||
return worker->deletePromise.Promise();
|
||||
}));
|
||||
#endif
|
||||
|
||||
#ifdef GETCONFIG
|
||||
exports.Set("getConfig", Napi::Function::New(initEnv, [&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
exports.Set(
|
||||
"getConfig",
|
||||
Napi::Function::New(
|
||||
initEnv, [&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
const Napi::Env env = info.Env();
|
||||
const auto wgName = info[0];
|
||||
if (!(wgName.IsString())) {
|
||||
Napi::Error::New(env, "Require wireguard interface name").ThrowAsJavaScriptException();
|
||||
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();
|
||||
Napi::Error::New(env, "interface name is so long")
|
||||
.ThrowAsJavaScriptException();
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
@ -93,7 +111,9 @@ Napi::Object Init(Napi::Env initEnv, Napi::Object exports) {
|
||||
#endif
|
||||
|
||||
#ifdef LISTDEV
|
||||
exports.Set("listDevices", Napi::Function::New(initEnv, [&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
exports.Set("listDevices",
|
||||
Napi::Function::New(
|
||||
initEnv, [&](const Napi::CallbackInfo &info) -> Napi::Value {
|
||||
const Napi::Env env = info.Env();
|
||||
auto worker = new listDevices(env);
|
||||
worker->Queue();
|
||||
|
@ -1,30 +1,31 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <wireguard-nt/include/wireguard.h>
|
||||
#include <windows.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <ws2def.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <netioapi.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include <iphlpapi.h>
|
||||
#include <netioapi.h>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <wireguard-nt/include/wireguard.h>
|
||||
#include <ws2def.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
// Function to check if the current user has administrator privileges
|
||||
bool IsRunAsAdmin()
|
||||
{
|
||||
bool IsRunAsAdmin() {
|
||||
BOOL fRet = FALSE;
|
||||
HANDLE hToken = NULL;
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
|
||||
TOKEN_ELEVATION Elevation;
|
||||
DWORD cbSize = sizeof(TOKEN_ELEVATION);
|
||||
if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) {
|
||||
if (GetTokenInformation(hToken, TokenElevation, &Elevation,
|
||||
sizeof(Elevation), &cbSize)) {
|
||||
fRet = Elevation.TokenIsElevated;
|
||||
}
|
||||
}
|
||||
if (hToken) CloseHandle(hToken);
|
||||
if (hToken)
|
||||
CloseHandle(hToken);
|
||||
return !!fRet;
|
||||
}
|
||||
|
||||
@ -38,12 +39,15 @@ int parse_dns_retries() {
|
||||
unsigned long ret;
|
||||
char *retries = getenv("WG_ENDPOINT_RESOLUTION_RETRIES"), *end;
|
||||
|
||||
if (!retries) return 15;
|
||||
if (!strcmp(retries, "infinity")) return -1;
|
||||
if (!retries)
|
||||
return 15;
|
||||
if (!strcmp(retries, "infinity"))
|
||||
return -1;
|
||||
|
||||
ret = strtoul(retries, &end, 10);
|
||||
if (*end || ret > INT_MAX) {
|
||||
fprintf(stderr, "Unable to parse WG_ENDPOINT_RESOLUTION_RETRIES: `%s'\n", retries);
|
||||
fprintf(stderr, "Unable to parse WG_ENDPOINT_RESOLUTION_RETRIES: `%s'\n",
|
||||
retries);
|
||||
exit(1);
|
||||
}
|
||||
return (int)ret;
|
||||
@ -53,7 +57,8 @@ void insertEndpoint(SOCKADDR_INET *endpoint, std::string value) {
|
||||
int ret, retries = parse_dns_retries();
|
||||
char *begin, *end;
|
||||
auto mmutable = strdup(value.c_str());
|
||||
if (!mmutable) throw std::string("strdup");
|
||||
if (!mmutable)
|
||||
throw std::string("strdup");
|
||||
if (!value.size()) {
|
||||
free(mmutable);
|
||||
throw std::string("Unable to parse empty endpoint");
|
||||
@ -63,7 +68,8 @@ void insertEndpoint(SOCKADDR_INET *endpoint, std::string value) {
|
||||
end = strchr(mmutable, ']');
|
||||
if (!end) {
|
||||
free(mmutable);
|
||||
throw std::string("Unable to find matching brace of endpoint: ").append(value);
|
||||
throw std::string("Unable to find matching brace of endpoint: ")
|
||||
.append(value);
|
||||
}
|
||||
*end++ = '\0';
|
||||
if (*end++ != ':' || !*end) {
|
||||
@ -80,22 +86,26 @@ void insertEndpoint(SOCKADDR_INET *endpoint, std::string value) {
|
||||
*end++ = '\0';
|
||||
}
|
||||
|
||||
|
||||
ADDRINFOA *resolved;
|
||||
// #define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
for (unsigned int timeout = 1000000;; timeout = ((20000000) < (timeout * 6 / 5) ? (20000000) : (timeout * 6 / 5))) {
|
||||
for (unsigned int timeout = 1000000;;
|
||||
timeout =
|
||||
((20000000) < (timeout * 6 / 5) ? (20000000) : (timeout * 6 / 5))) {
|
||||
// ret = getaddrinfo(begin, end, &hints, &resolved);
|
||||
ret = getaddrinfo(begin, end, NULL, &resolved);
|
||||
if (!ret) break;
|
||||
/* The set of return codes that are "permanent failures". All other possibilities are potentially transient.
|
||||
if (!ret)
|
||||
break;
|
||||
/* The set of return codes that are "permanent failures". All other
|
||||
*possibilities are potentially transient.
|
||||
*
|
||||
* This is according to https://sourceware.org/glibc/wiki/NameResolver which states:
|
||||
* "From the perspective of the application that calls getaddrinfo() it perhaps
|
||||
* doesn't matter that much since EAI_FAIL, EAI_NONAME and EAI_NODATA are all
|
||||
* permanent failure codes and the causes are all permanent failures in the
|
||||
* sense that there is no point in retrying later."
|
||||
* This is according to https://sourceware.org/glibc/wiki/NameResolver which
|
||||
*states: "From the perspective of the application that calls getaddrinfo()
|
||||
*it perhaps doesn't matter that much since EAI_FAIL, EAI_NONAME and
|
||||
*EAI_NODATA are all permanent failure codes and the causes are all
|
||||
*permanent failures in the sense that there is no point in retrying later."
|
||||
*
|
||||
* So this is what we do, except FreeBSD removed EAI_NODATA some time ago, so that's conditional.
|
||||
* So this is what we do, except FreeBSD removed EAI_NODATA some time ago,
|
||||
*so that's conditional.
|
||||
*/
|
||||
if (ret == EAI_NONAME || ret == EAI_FAIL ||
|
||||
#ifdef EAI_NODATA
|
||||
@ -108,8 +118,12 @@ void insertEndpoint(SOCKADDR_INET *endpoint, std::string value) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(timeout));
|
||||
}
|
||||
|
||||
if ((resolved->ai_family == AF_INET && resolved->ai_addrlen == sizeof(SOCKADDR_IN))) memcpy(&endpoint->Ipv4, resolved->ai_addr, resolved->ai_addrlen);
|
||||
else if (resolved->ai_family == AF_INET6 && resolved->ai_addrlen == sizeof(SOCKADDR_IN6)) memcpy(&endpoint->Ipv6, resolved->ai_addr, resolved->ai_addrlen);
|
||||
if ((resolved->ai_family == AF_INET &&
|
||||
resolved->ai_addrlen == sizeof(SOCKADDR_IN)))
|
||||
memcpy(&endpoint->Ipv4, resolved->ai_addr, resolved->ai_addrlen);
|
||||
else if (resolved->ai_family == AF_INET6 &&
|
||||
resolved->ai_addrlen == sizeof(SOCKADDR_IN6))
|
||||
memcpy(&endpoint->Ipv6, resolved->ai_addr, resolved->ai_addrlen);
|
||||
else {
|
||||
freeaddrinfo(resolved);
|
||||
throw std::string("Neither IPv4 nor IPv6 address found: ").append(value);
|
||||
@ -119,17 +133,25 @@ void insertEndpoint(SOCKADDR_INET *endpoint, std::string value) {
|
||||
}
|
||||
|
||||
std::string parseEndpoint(SOCKADDR_INET *input) {
|
||||
if (!(input->si_family == AF_INET || input->si_family == AF_INET6)) return "";
|
||||
if (!(input->si_family == AF_INET || input->si_family == AF_INET6))
|
||||
return "";
|
||||
char saddr[INET6_ADDRSTRLEN];
|
||||
input->si_family == AF_INET ? inet_ntop(AF_INET, &input->Ipv4.sin_addr, saddr, INET_ADDRSTRLEN) : inet_ntop(AF_INET6, &input->Ipv6.sin6_addr, saddr, INET6_ADDRSTRLEN);
|
||||
input->si_family == AF_INET
|
||||
? inet_ntop(AF_INET, &input->Ipv4.sin_addr, saddr, INET_ADDRSTRLEN)
|
||||
: inet_ntop(AF_INET6, &input->Ipv6.sin6_addr, saddr, INET6_ADDRSTRLEN);
|
||||
|
||||
if (input->si_family == AF_INET6) return std::string("[").append(saddr).append("]:").append(std::to_string(htons(input->Ipv6.sin6_port)));
|
||||
return std::string(saddr).append(":").append(std::to_string(htons(input->Ipv4.sin_port)));
|
||||
if (input->si_family == AF_INET6)
|
||||
return std::string("[").append(saddr).append("]:").append(
|
||||
std::to_string(htons(input->Ipv6.sin6_port)));
|
||||
return std::string(saddr).append(":").append(
|
||||
std::to_string(htons(input->Ipv4.sin_port)));
|
||||
}
|
||||
|
||||
std::string insertIpAddr(NET_LUID InterfaceLuid, std::string IPv4, std::string IPv6) {
|
||||
std::string insertIpAddr(NET_LUID InterfaceLuid, std::string IPv4,
|
||||
std::string IPv6) {
|
||||
NET_IFINDEX ind;
|
||||
if (ConvertInterfaceLuidToIndex(&InterfaceLuid, &ind) != NO_ERROR) return "Cannot get interface index";
|
||||
if (ConvertInterfaceLuidToIndex(&InterfaceLuid, &ind) != NO_ERROR)
|
||||
return "Cannot get interface index";
|
||||
|
||||
// IPv4
|
||||
if (IPv4.size() > 0) {
|
||||
@ -137,10 +159,13 @@ std::string insertIpAddr(NET_LUID InterfaceLuid, std::string IPv4, std::string I
|
||||
ULONG NTEInstance = 0;
|
||||
UINT iaIPAddress;
|
||||
inet_pton(AF_INET, IPv4.c_str(), &iaIPAddress);
|
||||
auto status = AddIPAddress(iaIPAddress, NULL, ind, &NTEContext, &NTEInstance);
|
||||
auto status =
|
||||
AddIPAddress(iaIPAddress, NULL, ind, &NTEContext, &NTEInstance);
|
||||
if (status != NO_ERROR) {
|
||||
if (status == 5010) {
|
||||
} else return std::string("Cannot set IPv4 interface, error code: ").append(std::to_string(status));
|
||||
} else
|
||||
return std::string("Cannot set IPv4 interface, error code: ")
|
||||
.append(std::to_string(status));
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +180,8 @@ std::string insertIpAddr(NET_LUID InterfaceLuid, std::string IPv4, std::string I
|
||||
|
||||
std::vector<std::string> getIpAddr(NET_LUID InterfaceLuid) {
|
||||
NET_IFINDEX ind;
|
||||
if (ConvertInterfaceLuidToIndex(&InterfaceLuid, &ind) != NO_ERROR) throw std::string("Cannot get interface index");
|
||||
if (ConvertInterfaceLuidToIndex(&InterfaceLuid, &ind) != NO_ERROR)
|
||||
throw std::string("Cannot get interface index");
|
||||
std::vector<std::string> ips;
|
||||
|
||||
IP_ADAPTER_INFO *pAdapterInfo;
|
||||
@ -167,13 +193,18 @@ std::vector<std::string> getIpAddr(NET_LUID InterfaceLuid) {
|
||||
free(pAdapterInfo);
|
||||
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
|
||||
}
|
||||
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) != ERROR_SUCCESS) throw std::string("GetAdaptersInfo call failed with ").append(std::to_string(dwRetVal));
|
||||
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) != ERROR_SUCCESS)
|
||||
throw std::string("GetAdaptersInfo call failed with ")
|
||||
.append(std::to_string(dwRetVal));
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
if (pAdapter->Index == ind) ips.push_back(std::string(pAdapter->IpAddressList.IpAddress.String).append("/32"));
|
||||
if (pAdapter->Index == ind)
|
||||
ips.push_back(
|
||||
std::string(pAdapter->IpAddressList.IpAddress.String).append("/32"));
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
if (pAdapterInfo) free(pAdapterInfo);
|
||||
if (pAdapterInfo)
|
||||
free(pAdapterInfo);
|
||||
|
||||
return ips;
|
||||
}
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <ipexport.h>
|
||||
#include <ifdef.h>
|
||||
#include <ipexport.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2ipdef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -31,7 +31,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4324) /* structure was padded due to alignment specifier */
|
||||
#pragma warning( \
|
||||
disable : 4324) /* structure was padded due to alignment specifier */
|
||||
|
||||
/**
|
||||
* A handle representing WireGuard adapter
|
||||
@ -41,54 +42,60 @@ typedef struct _WIREGUARD_ADAPTER *WIREGUARD_ADAPTER_HANDLE;
|
||||
/**
|
||||
* Creates a new WireGuard adapter.
|
||||
*
|
||||
* @param Name The requested name of the adapter. Zero-terminated string of up to MAX_ADAPTER_NAME-1
|
||||
* characters.
|
||||
* @param Name The requested name of the adapter. Zero-terminated
|
||||
* string of up to MAX_ADAPTER_NAME-1 characters.
|
||||
*
|
||||
* @param TunnelType Name of the adapter tunnel type. Zero-terminated string of up to MAX_ADAPTER_NAME-1
|
||||
* characters.
|
||||
* @param TunnelType Name of the adapter tunnel type. Zero-terminated string
|
||||
* of up to MAX_ADAPTER_NAME-1 characters.
|
||||
*
|
||||
* @param RequestedGUID The GUID of the created network adapter, which then influences NLA generation deterministically.
|
||||
* If it is set to NULL, the GUID is chosen by the system at random, and hence a new NLA entry is
|
||||
* created for each new adapter. It is called "requested" GUID because the API it uses is
|
||||
* completely undocumented, and so there could be minor interesting complications with its usage.
|
||||
* @param RequestedGUID The GUID of the created network adapter, which then
|
||||
* influences NLA generation deterministically. If it is set to NULL, the GUID
|
||||
* is chosen by the system at random, and hence a new NLA entry is created for
|
||||
* each new adapter. It is called "requested" GUID because the API it uses is
|
||||
* completely undocumented, and so there could be minor
|
||||
* interesting complications with its usage.
|
||||
*
|
||||
* @return If the function succeeds, the return value is the adapter handle. Must be released with
|
||||
* WireGuardCloseAdapter. If the function fails, the return value is NULL. To get extended error information, call
|
||||
* GetLastError.
|
||||
* @return If the function succeeds, the return value is the adapter handle.
|
||||
* Must be released with WireGuardCloseAdapter. If the function fails, the
|
||||
* return value is NULL. To get extended error information, call GetLastError.
|
||||
*/
|
||||
typedef _Must_inspect_result_
|
||||
_Return_type_success_(return != NULL)
|
||||
_Post_maybenull_
|
||||
WIREGUARD_ADAPTER_HANDLE(WINAPI WIREGUARD_CREATE_ADAPTER_FUNC)
|
||||
(_In_z_ LPCWSTR Name, _In_z_ LPCWSTR TunnelType, _In_opt_ const GUID *RequestedGUID);
|
||||
_Return_type_success_(return != NULL) _Post_maybenull_
|
||||
WIREGUARD_ADAPTER_HANDLE(WINAPI WIREGUARD_CREATE_ADAPTER_FUNC)(
|
||||
_In_z_ LPCWSTR Name, _In_z_ LPCWSTR TunnelType,
|
||||
_In_opt_ const GUID *RequestedGUID);
|
||||
|
||||
/**
|
||||
* Opens an existing WireGuard adapter.
|
||||
*
|
||||
* @param Name The requested name of the adapter. Zero-terminated string of up to MAX_ADAPTER_NAME-1
|
||||
* characters.
|
||||
* @param Name The requested name of the adapter. Zero-terminated
|
||||
* string of up to MAX_ADAPTER_NAME-1 characters.
|
||||
*
|
||||
* @return If the function succeeds, the return value is the adapter handle. Must be released with
|
||||
* WireGuardCloseAdapter. If the function fails, the return value is NULL. To get extended error information, call
|
||||
* GetLastError.
|
||||
* @return If the function succeeds, the return value is the adapter handle.
|
||||
* Must be released with WireGuardCloseAdapter. If the function fails, the
|
||||
* return value is NULL. To get extended error information, call GetLastError.
|
||||
*/
|
||||
typedef _Must_inspect_result_
|
||||
_Return_type_success_(return != NULL)
|
||||
_Post_maybenull_
|
||||
WIREGUARD_ADAPTER_HANDLE(WINAPI WIREGUARD_OPEN_ADAPTER_FUNC)(_In_z_ LPCWSTR Name);
|
||||
_Return_type_success_(return != NULL) _Post_maybenull_
|
||||
WIREGUARD_ADAPTER_HANDLE(WINAPI WIREGUARD_OPEN_ADAPTER_FUNC)(
|
||||
_In_z_ LPCWSTR Name);
|
||||
|
||||
/**
|
||||
* Releases WireGuard adapter resources and, if adapter was created with WireGuardCreateAdapter, removes adapter.
|
||||
* Releases WireGuard adapter resources and, if adapter was created with
|
||||
* WireGuardCreateAdapter, removes adapter.
|
||||
*
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter.
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or
|
||||
* WireGuardOpenAdapter.
|
||||
*/
|
||||
typedef VOID(WINAPI WIREGUARD_CLOSE_ADAPTER_FUNC)(_In_opt_ WIREGUARD_ADAPTER_HANDLE Adapter);
|
||||
typedef VOID(WINAPI WIREGUARD_CLOSE_ADAPTER_FUNC)(
|
||||
_In_opt_ WIREGUARD_ADAPTER_HANDLE Adapter);
|
||||
|
||||
/**
|
||||
* Deletes the WireGuard driver if there are no more adapters in use.
|
||||
*
|
||||
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
|
||||
* get extended error information, call GetLastError.
|
||||
* @return If the function succeeds, the return value is nonzero. If the
|
||||
* function fails, the return value is zero. To get extended error information,
|
||||
* call GetLastError.
|
||||
*/
|
||||
typedef _Return_type_success_(return != FALSE)
|
||||
BOOL(WINAPI WIREGUARD_DELETE_DRIVER_FUNC)(VOID);
|
||||
@ -96,17 +103,20 @@ BOOL(WINAPI WIREGUARD_DELETE_DRIVER_FUNC)(VOID);
|
||||
/**
|
||||
* Returns the LUID of the adapter.
|
||||
*
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or
|
||||
* WireGuardOpenAdapter
|
||||
*
|
||||
* @param Luid Pointer to LUID to receive adapter LUID.
|
||||
*/
|
||||
typedef VOID(WINAPI WIREGUARD_GET_ADAPTER_LUID_FUNC)(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _Out_ NET_LUID *Luid);
|
||||
typedef VOID(WINAPI WIREGUARD_GET_ADAPTER_LUID_FUNC)(
|
||||
_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _Out_ NET_LUID *Luid);
|
||||
|
||||
/**
|
||||
* Determines the version of the WireGuard driver currently loaded.
|
||||
*
|
||||
* @return If the function succeeds, the return value is the version number. If the function fails, the return value is
|
||||
* zero. To get extended error information, call GetLastError. Possible errors include the following:
|
||||
* @return If the function succeeds, the return value is the version number. If
|
||||
* the function fails, the return value is zero. To get extended error
|
||||
* information, call GetLastError. Possible errors include the following:
|
||||
* ERROR_FILE_NOT_FOUND WireGuard not loaded
|
||||
*/
|
||||
typedef _Return_type_success_(return != 0)
|
||||
@ -115,8 +125,7 @@ DWORD(WINAPI WIREGUARD_GET_RUNNING_DRIVER_VERSION_FUNC)(VOID);
|
||||
/**
|
||||
* Determines the level of logging, passed to WIREGUARD_LOGGER_CALLBACK.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
WIREGUARD_LOG_INFO, /**< Informational */
|
||||
WIREGUARD_LOG_WARN, /**< Warning */
|
||||
WIREGUARD_LOG_ERR /**< Error */
|
||||
@ -127,177 +136,201 @@ typedef enum
|
||||
*
|
||||
* @param Level Message level.
|
||||
*
|
||||
* @param Timestamp Message timestamp in in 100ns intervals since 1601-01-01 UTC.
|
||||
* @param Timestamp Message timestamp in in 100ns intervals since 1601-01-01
|
||||
* UTC.
|
||||
*
|
||||
* @param Message Message text.
|
||||
*/
|
||||
typedef VOID(CALLBACK *WIREGUARD_LOGGER_CALLBACK)(
|
||||
_In_ WIREGUARD_LOGGER_LEVEL Level,
|
||||
_In_ DWORD64 Timestamp,
|
||||
_In_ WIREGUARD_LOGGER_LEVEL Level, _In_ DWORD64 Timestamp,
|
||||
_In_z_ LPCWSTR Message);
|
||||
|
||||
/**
|
||||
* Sets logger callback function.
|
||||
*
|
||||
* @param NewLogger Pointer to callback function to use as a new global logger. NewLogger may be called from various
|
||||
* threads concurrently. Should the logging require serialization, you must handle serialization in
|
||||
* NewLogger. Set to NULL to disable.
|
||||
* @param NewLogger Pointer to callback function to use as a new global
|
||||
* logger. NewLogger may be called from various threads concurrently. Should the
|
||||
* logging require serialization, you must handle serialization in NewLogger.
|
||||
* Set to NULL to disable.
|
||||
*/
|
||||
typedef VOID(WINAPI WIREGUARD_SET_LOGGER_FUNC)(_In_ WIREGUARD_LOGGER_CALLBACK NewLogger);
|
||||
typedef VOID(WINAPI WIREGUARD_SET_LOGGER_FUNC)(
|
||||
_In_ WIREGUARD_LOGGER_CALLBACK NewLogger);
|
||||
|
||||
/**
|
||||
* Whether and how logs from the driver are collected for the callback function.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
WIREGUARD_ADAPTER_LOG_OFF, /**< No logs are generated from the driver. */
|
||||
WIREGUARD_ADAPTER_LOG_ON, /**< Logs are generated from the driver. */
|
||||
WIREGUARD_ADAPTER_LOG_ON_WITH_PREFIX /**< Logs are generated from the driver, index-prefixed. */
|
||||
WIREGUARD_ADAPTER_LOG_ON_WITH_PREFIX /**< Logs are generated from the driver,
|
||||
index-prefixed. */
|
||||
} WIREGUARD_ADAPTER_LOG_STATE;
|
||||
|
||||
/**
|
||||
* Sets whether and how the adapter logs to the logger previously set up with WireGuardSetLogger.
|
||||
* Sets whether and how the adapter logs to the logger previously set up with
|
||||
* WireGuardSetLogger.
|
||||
*
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or
|
||||
* WireGuardOpenAdapter
|
||||
*
|
||||
* @param LogState Adapter logging state.
|
||||
*
|
||||
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
|
||||
* get extended error information, call GetLastError.
|
||||
* @return If the function succeeds, the return value is nonzero. If the
|
||||
* function fails, the return value is zero. To get extended error information,
|
||||
* call GetLastError.
|
||||
*/
|
||||
typedef _Return_type_success_(return != FALSE)
|
||||
BOOL(WINAPI WIREGUARD_SET_ADAPTER_LOGGING_FUNC)
|
||||
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _In_ WIREGUARD_ADAPTER_LOG_STATE LogState);
|
||||
BOOL(WINAPI WIREGUARD_SET_ADAPTER_LOGGING_FUNC)(
|
||||
_In_ WIREGUARD_ADAPTER_HANDLE Adapter,
|
||||
_In_ WIREGUARD_ADAPTER_LOG_STATE LogState);
|
||||
|
||||
/**
|
||||
* Determines the state of the adapter.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
WIREGUARD_ADAPTER_STATE_DOWN, /**< Down */
|
||||
WIREGUARD_ADAPTER_STATE_UP, /**< Up */
|
||||
} WIREGUARD_ADAPTER_STATE;
|
||||
|
||||
/**
|
||||
* Sets the adapter state of the WireGuard adapter. Note: sockets are owned by the process that sets the state to up.
|
||||
* Sets the adapter state of the WireGuard adapter. Note: sockets are owned by
|
||||
* the process that sets the state to up.
|
||||
*
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or
|
||||
* WireGuardOpenAdapter
|
||||
*
|
||||
* @param State Adapter state.
|
||||
*
|
||||
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
|
||||
* get extended error information, call GetLastError.
|
||||
* @return If the function succeeds, the return value is nonzero. If the
|
||||
* function fails, the return value is zero. To get extended error information,
|
||||
* call GetLastError.
|
||||
*/
|
||||
typedef _Return_type_success_(return != FALSE)
|
||||
BOOL(WINAPI WIREGUARD_SET_ADAPTER_STATE_FUNC)
|
||||
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _In_ WIREGUARD_ADAPTER_STATE State);
|
||||
BOOL(WINAPI WIREGUARD_SET_ADAPTER_STATE_FUNC)(
|
||||
_In_ WIREGUARD_ADAPTER_HANDLE Adapter,
|
||||
_In_ WIREGUARD_ADAPTER_STATE State);
|
||||
|
||||
/**
|
||||
* Gets the adapter state of the WireGuard adapter.
|
||||
*
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or
|
||||
* WireGuardOpenAdapter
|
||||
*
|
||||
* @param State Pointer to adapter state.
|
||||
*
|
||||
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
|
||||
* get extended error information, call GetLastError.
|
||||
* @return If the function succeeds, the return value is nonzero. If the
|
||||
* function fails, the return value is zero. To get extended error information,
|
||||
* call GetLastError.
|
||||
*/
|
||||
typedef _Must_inspect_result_
|
||||
_Return_type_success_(return != FALSE)
|
||||
BOOL(WINAPI WIREGUARD_GET_ADAPTER_STATE_FUNC)
|
||||
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _Out_ WIREGUARD_ADAPTER_STATE *State);
|
||||
typedef _Must_inspect_result_ _Return_type_success_(return != FALSE)
|
||||
BOOL(WINAPI WIREGUARD_GET_ADAPTER_STATE_FUNC)(
|
||||
_In_ WIREGUARD_ADAPTER_HANDLE Adapter,
|
||||
_Out_ WIREGUARD_ADAPTER_STATE *State);
|
||||
|
||||
#define WIREGUARD_KEY_LENGTH 32
|
||||
|
||||
typedef struct _WIREGUARD_ALLOWED_IP WIREGUARD_ALLOWED_IP;
|
||||
struct ALIGNED(8) _WIREGUARD_ALLOWED_IP
|
||||
{
|
||||
union
|
||||
{
|
||||
struct ALIGNED(8) _WIREGUARD_ALLOWED_IP {
|
||||
union {
|
||||
IN_ADDR V4;
|
||||
IN6_ADDR V6;
|
||||
} Address; /**< IP address */
|
||||
ADDRESS_FAMILY AddressFamily; /**< Address family, either AF_INET or AF_INET6 */
|
||||
ADDRESS_FAMILY
|
||||
AddressFamily; /**< Address family, either AF_INET or AF_INET6 */
|
||||
BYTE Cidr; /**< CIDR of allowed IPs */
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
WIREGUARD_PEER_HAS_PUBLIC_KEY = 1 << 0, /**< The PublicKey field is set */
|
||||
WIREGUARD_PEER_HAS_PRESHARED_KEY = 1 << 1, /**< The PresharedKey field is set */
|
||||
WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE = 1 << 2, /**< The PersistentKeepAlive field is set */
|
||||
WIREGUARD_PEER_HAS_PRESHARED_KEY = 1
|
||||
<< 1, /**< The PresharedKey field is set */
|
||||
WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE =
|
||||
1 << 2, /**< The PersistentKeepAlive field is set */
|
||||
WIREGUARD_PEER_HAS_ENDPOINT = 1 << 3, /**< The Endpoint field is set */
|
||||
WIREGUARD_PEER_REPLACE_ALLOWED_IPS = 1 << 5, /**< Remove all allowed IPs before adding new ones */
|
||||
WIREGUARD_PEER_REPLACE_ALLOWED_IPS =
|
||||
1 << 5, /**< Remove all allowed IPs before adding new ones */
|
||||
WIREGUARD_PEER_REMOVE = 1 << 6, /**< Remove specified peer */
|
||||
WIREGUARD_PEER_UPDATE = 1 << 7 /**< Do not add a new peer */
|
||||
} WIREGUARD_PEER_FLAG;
|
||||
|
||||
typedef struct _WIREGUARD_PEER WIREGUARD_PEER;
|
||||
struct ALIGNED(8) _WIREGUARD_PEER
|
||||
{
|
||||
struct ALIGNED(8) _WIREGUARD_PEER {
|
||||
WIREGUARD_PEER_FLAG Flags; /**< Bitwise combination of flags */
|
||||
DWORD Reserved; /**< Reserved; must be zero */
|
||||
BYTE PublicKey[WIREGUARD_KEY_LENGTH]; /**< Public key, the peer's primary identifier */
|
||||
BYTE PresharedKey[WIREGUARD_KEY_LENGTH]; /**< Preshared key for additional layer of post-quantum resistance */
|
||||
BYTE PublicKey[WIREGUARD_KEY_LENGTH]; /**< Public key, the peer's primary
|
||||
identifier */
|
||||
BYTE
|
||||
PresharedKey[WIREGUARD_KEY_LENGTH]; /**< Preshared key for additional
|
||||
layer of post-quantum resistance */
|
||||
WORD PersistentKeepalive; /**< Seconds interval, or 0 to disable */
|
||||
SOCKADDR_INET Endpoint; /**< Endpoint, with IP address and UDP port number*/
|
||||
DWORD64 TxBytes; /**< Number of bytes transmitted */
|
||||
DWORD64 RxBytes; /**< Number of bytes received */
|
||||
DWORD64 LastHandshake; /**< Time of the last handshake, in 100ns intervals since 1601-01-01 UTC */
|
||||
DWORD AllowedIPsCount; /**< Number of allowed IP structs following this struct */
|
||||
DWORD64 LastHandshake; /**< Time of the last handshake, in 100ns intervals
|
||||
since 1601-01-01 UTC */
|
||||
DWORD AllowedIPsCount; /**< Number of allowed IP structs following this struct
|
||||
*/
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WIREGUARD_INTERFACE_HAS_PUBLIC_KEY = (1 << 0), /**< The PublicKey field is set */
|
||||
WIREGUARD_INTERFACE_HAS_PRIVATE_KEY = (1 << 1), /**< The PrivateKey field is set */
|
||||
WIREGUARD_INTERFACE_HAS_LISTEN_PORT = (1 << 2), /**< The ListenPort field is set */
|
||||
WIREGUARD_INTERFACE_REPLACE_PEERS = (1 << 3) /**< Remove all peers before adding new ones */
|
||||
typedef enum {
|
||||
WIREGUARD_INTERFACE_HAS_PUBLIC_KEY =
|
||||
(1 << 0), /**< The PublicKey field is set */
|
||||
WIREGUARD_INTERFACE_HAS_PRIVATE_KEY =
|
||||
(1 << 1), /**< The PrivateKey field is set */
|
||||
WIREGUARD_INTERFACE_HAS_LISTEN_PORT =
|
||||
(1 << 2), /**< The ListenPort field is set */
|
||||
WIREGUARD_INTERFACE_REPLACE_PEERS =
|
||||
(1 << 3) /**< Remove all peers before adding new ones */
|
||||
} WIREGUARD_INTERFACE_FLAG;
|
||||
|
||||
typedef struct _WIREGUARD_INTERFACE WIREGUARD_INTERFACE;
|
||||
struct ALIGNED(8) _WIREGUARD_INTERFACE
|
||||
{
|
||||
struct ALIGNED(8) _WIREGUARD_INTERFACE {
|
||||
WIREGUARD_INTERFACE_FLAG Flags; /**< Bitwise combination of flags */
|
||||
WORD ListenPort; /**< Port for UDP listen socket, or 0 to choose randomly */
|
||||
BYTE PrivateKey[WIREGUARD_KEY_LENGTH]; /**< Private key of interface */
|
||||
BYTE PublicKey[WIREGUARD_KEY_LENGTH]; /**< Corresponding public key of private key */
|
||||
BYTE PublicKey[WIREGUARD_KEY_LENGTH]; /**< Corresponding public key of private
|
||||
key */
|
||||
DWORD PeersCount; /**< Number of peer structs following this struct */
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the configuration of the WireGuard adapter.
|
||||
*
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or
|
||||
* WireGuardOpenAdapter
|
||||
*
|
||||
* @param Config Configuration for the adapter.
|
||||
*
|
||||
* @param Bytes Number of bytes in Config allocation.
|
||||
*
|
||||
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
|
||||
* get extended error information, call GetLastError.
|
||||
* @return If the function succeeds, the return value is nonzero. If the
|
||||
* function fails, the return value is zero. To get extended error information,
|
||||
* call GetLastError.
|
||||
*/
|
||||
typedef _Return_type_success_(return != FALSE)
|
||||
BOOL(WINAPI WIREGUARD_SET_CONFIGURATION_FUNC)
|
||||
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _In_reads_bytes_(Bytes) const WIREGUARD_INTERFACE *Config, _In_ DWORD Bytes);
|
||||
BOOL(WINAPI WIREGUARD_SET_CONFIGURATION_FUNC)(
|
||||
_In_ WIREGUARD_ADAPTER_HANDLE Adapter,
|
||||
_In_reads_bytes_(Bytes) const WIREGUARD_INTERFACE *Config,
|
||||
_In_ DWORD Bytes);
|
||||
|
||||
/**
|
||||
* Gets the configuration of the WireGuard adapter.
|
||||
*
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
|
||||
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or
|
||||
* WireGuardOpenAdapter
|
||||
*
|
||||
* @param Config Configuration for the adapter.
|
||||
*
|
||||
* @param Bytes Pointer to number of bytes in Config allocation.
|
||||
*
|
||||
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
|
||||
* get extended error information, call GetLastError, which if ERROR_MORE_DATA, Bytes is updated with the
|
||||
* @return If the function succeeds, the return value is nonzero. If the
|
||||
* function fails, the return value is zero. To get extended error information,
|
||||
* call GetLastError, which if ERROR_MORE_DATA, Bytes is updated with the
|
||||
* required size.
|
||||
*/
|
||||
typedef _Must_inspect_result_
|
||||
_Return_type_success_(return != FALSE)
|
||||
BOOL(WINAPI WIREGUARD_GET_CONFIGURATION_FUNC)
|
||||
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter,
|
||||
typedef _Must_inspect_result_ _Return_type_success_(return != FALSE)
|
||||
BOOL(WINAPI WIREGUARD_GET_CONFIGURATION_FUNC)(
|
||||
_In_ WIREGUARD_ADAPTER_HANDLE Adapter,
|
||||
_Out_writes_bytes_all_(*Bytes) WIREGUARD_INTERFACE *Config,
|
||||
_Inout_ DWORD *Bytes);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user