mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2026-04-24 07:49:26 +03:00
Merge PR #1200: Implement support for WireGuard
This commit is contained in:
+218
-4
@@ -1509,6 +1509,9 @@ PACK *AdminDispatch(RPC *rpc, char *name, PACK *p)
|
||||
DECLARE_RPC_EX("GetServerCipherList", RPC_STR, StGetServerCipherList, InRpcStr, OutRpcStr, FreeRpcStr)
|
||||
DECLARE_RPC_EX("GetServerCipher", RPC_STR, StGetServerCipher, InRpcStr, OutRpcStr, FreeRpcStr)
|
||||
DECLARE_RPC_EX("SetServerCipher", RPC_STR, StSetServerCipher, InRpcStr, OutRpcStr, FreeRpcStr)
|
||||
DECLARE_RPC_EX("AddWgk", RPC_WGK, StAddWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
|
||||
DECLARE_RPC_EX("DeleteWgk", RPC_WGK, StDeleteWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
|
||||
DECLARE_RPC_EX("EnumWgk", RPC_WGK, StEnumWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
|
||||
DECLARE_RPC("CreateHub", RPC_CREATE_HUB, StCreateHub, InRpcCreateHub, OutRpcCreateHub)
|
||||
DECLARE_RPC("SetHub", RPC_CREATE_HUB, StSetHub, InRpcCreateHub, OutRpcCreateHub)
|
||||
DECLARE_RPC("GetHub", RPC_CREATE_HUB, StGetHub, InRpcCreateHub, OutRpcCreateHub)
|
||||
@@ -1693,6 +1696,9 @@ DECLARE_SC_EX("GetServerCert", RPC_KEY_PAIR, ScGetServerCert, InRpcKeyPair, OutR
|
||||
DECLARE_SC_EX("GetServerCipherList", RPC_STR, ScGetServerCipherList, InRpcStr, OutRpcStr, FreeRpcStr)
|
||||
DECLARE_SC_EX("GetServerCipher", RPC_STR, ScGetServerCipher, InRpcStr, OutRpcStr, FreeRpcStr)
|
||||
DECLARE_SC_EX("SetServerCipher", RPC_STR, ScSetServerCipher, InRpcStr, OutRpcStr, FreeRpcStr)
|
||||
DECLARE_SC_EX("AddWgk", RPC_WGK, ScAddWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
|
||||
DECLARE_SC_EX("DeleteWgk", RPC_WGK, ScDeleteWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
|
||||
DECLARE_SC_EX("EnumWgk", RPC_WGK, ScEnumWgk, InRpcWgk, OutRpcWgk, FreeRpcWgk)
|
||||
DECLARE_SC("CreateHub", RPC_CREATE_HUB, ScCreateHub, InRpcCreateHub, OutRpcCreateHub)
|
||||
DECLARE_SC("SetHub", RPC_CREATE_HUB, ScSetHub, InRpcCreateHub, OutRpcCreateHub)
|
||||
DECLARE_SC("GetHub", RPC_CREATE_HUB, ScGetHub, InRpcCreateHub, OutRpcCreateHub)
|
||||
@@ -9061,9 +9067,12 @@ UINT StGetHub(ADMIN *a, RPC_CREATE_HUB *t)
|
||||
{
|
||||
StrCpy(t->HubName, sizeof(t->HubName), h->Name);
|
||||
t->Online = h->Offline ? false : true;
|
||||
t->HubType = h->Type;
|
||||
|
||||
t->HubOption.DefaultGateway = h->Option->DefaultGateway;
|
||||
t->HubOption.DefaultSubnet = h->Option->DefaultSubnet;
|
||||
t->HubOption.MaxSession = h->Option->MaxSession;
|
||||
t->HubOption.NoEnum = h->Option->NoEnum;
|
||||
t->HubType = h->Type;
|
||||
}
|
||||
Unlock(h->lock);
|
||||
|
||||
@@ -9090,7 +9099,6 @@ UINT StSetHub(ADMIN *a, RPC_CREATE_HUB *t)
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
CHECK_RIGHT;
|
||||
NO_SUPPORT_FOR_BRIDGE;
|
||||
|
||||
@@ -9175,8 +9183,12 @@ UINT StSetHub(ADMIN *a, RPC_CREATE_HUB *t)
|
||||
else
|
||||
{
|
||||
h->Type = t->HubType;
|
||||
|
||||
h->Option->DefaultGateway = t->HubOption.DefaultGateway;
|
||||
h->Option->DefaultSubnet = t->HubOption.DefaultSubnet;
|
||||
h->Option->MaxSession = t->HubOption.MaxSession;
|
||||
h->Option->NoEnum = t->HubOption.NoEnum;
|
||||
|
||||
if (IsZero(t->HashedPassword, sizeof(t->HashedPassword)) == false &&
|
||||
IsZero(t->SecurePassword, sizeof(t->SecurePassword)) == false)
|
||||
{
|
||||
@@ -9234,8 +9246,6 @@ UINT StCreateHub(ADMIN *a, RPC_CREATE_HUB *t)
|
||||
return ERR_NOT_FARM_CONTROLLER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (IsEmptyStr(t->HubName) || IsSafeStr(t->HubName) == false)
|
||||
{
|
||||
return ERR_INVALID_PARAMETER;
|
||||
@@ -9279,6 +9289,8 @@ UINT StCreateHub(ADMIN *a, RPC_CREATE_HUB *t)
|
||||
|
||||
// Create a hub object
|
||||
Zero(&o, sizeof(o));
|
||||
o.DefaultGateway = t->HubOption.DefaultGateway;
|
||||
o.DefaultSubnet = t->HubOption.DefaultSubnet;
|
||||
o.MaxSession = t->HubOption.MaxSession;
|
||||
o.NoEnum = t->HubOption.NoEnum;
|
||||
|
||||
@@ -9497,6 +9509,144 @@ UINT StSetServerCert(ADMIN *a, RPC_KEY_PAIR *t)
|
||||
return ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
// Add a WireGuard key to the allowed key list
|
||||
UINT StAddWgk(ADMIN *a, RPC_WGK *t)
|
||||
{
|
||||
UINT ret = ERR_NO_ERROR;
|
||||
SERVER *s = a->Server;
|
||||
CEDAR *c = s->Cedar;
|
||||
LIST *to_add;
|
||||
|
||||
SERVER_ADMIN_ONLY;
|
||||
|
||||
to_add = NewListFast(NULL);
|
||||
|
||||
LockList(c->WgkList);
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < t->Num; ++i)
|
||||
{
|
||||
WGK *rpc_wgk = &t->Wgks[i];
|
||||
WGK *wgk;
|
||||
|
||||
if (IsEmptyStr(rpc_wgk->Key))
|
||||
{
|
||||
ret = ERR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Search(c->WgkList, rpc_wgk) != NULL)
|
||||
{
|
||||
ret = ERR_OBJECT_EXISTS;
|
||||
break;
|
||||
}
|
||||
|
||||
wgk = Malloc(sizeof(WGK));
|
||||
StrCpy(wgk->Key, sizeof(wgk->Key), rpc_wgk->Key);
|
||||
StrCpy(wgk->Hub, sizeof(wgk->Hub), rpc_wgk->Hub);
|
||||
StrCpy(wgk->User, sizeof(wgk->User), rpc_wgk->User);
|
||||
|
||||
Add(to_add, wgk);
|
||||
}
|
||||
|
||||
for (i = 0; i < LIST_NUM(to_add); ++i)
|
||||
{
|
||||
WGK *wgk = LIST_DATA(to_add, i);
|
||||
ret == ERR_NO_ERROR ? Add(c->WgkList, wgk) : Free(wgk);
|
||||
}
|
||||
}
|
||||
UnlockList(c->WgkList);
|
||||
|
||||
if (ret == ERR_NO_ERROR)
|
||||
{
|
||||
ALog(a, NULL, "LA_ADD_WGK", LIST_NUM(to_add));
|
||||
IncrementServerConfigRevision(a->Server);
|
||||
}
|
||||
|
||||
ReleaseList(to_add);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Delete a WireGuard key from the allowed key list
|
||||
UINT StDeleteWgk(ADMIN *a, RPC_WGK *t)
|
||||
{
|
||||
UINT ret = ERR_NO_ERROR;
|
||||
SERVER *s = a->Server;
|
||||
CEDAR *c = s->Cedar;
|
||||
LIST *to_delete;
|
||||
|
||||
SERVER_ADMIN_ONLY;
|
||||
|
||||
to_delete = NewListFast(NULL);
|
||||
|
||||
LockList(c->WgkList);
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < t->Num; ++i)
|
||||
{
|
||||
WGK *wgk = Search(c->WgkList, &t->Wgks[i]);
|
||||
if (wgk == NULL)
|
||||
{
|
||||
ret = ERR_OBJECT_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
Add(to_delete, wgk);
|
||||
}
|
||||
|
||||
if (ret == ERR_NO_ERROR)
|
||||
{
|
||||
for (i = 0; i < LIST_NUM(to_delete); ++i)
|
||||
{
|
||||
WGK *wgk = LIST_DATA(to_delete, i);
|
||||
Delete(c->WgkList, wgk);
|
||||
Free(wgk);
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockList(c->WgkList);
|
||||
|
||||
if (ret == ERR_NO_ERROR)
|
||||
{
|
||||
ALog(a, NULL, "LA_DELETE_WGK", LIST_NUM(to_delete));
|
||||
IncrementServerConfigRevision(a->Server);
|
||||
}
|
||||
|
||||
ReleaseList(to_delete);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// List the allowed WireGuard keys
|
||||
UINT StEnumWgk(ADMIN *a, RPC_WGK *t)
|
||||
{
|
||||
SERVER *s = a->Server;
|
||||
CEDAR *c = s->Cedar;
|
||||
|
||||
SERVER_ADMIN_ONLY;
|
||||
|
||||
LockList(c->WgkList);
|
||||
{
|
||||
UINT i;
|
||||
t->Num = LIST_NUM(c->WgkList);
|
||||
t->Wgks = Malloc(sizeof(WGK) * t->Num);
|
||||
|
||||
for (i = 0; i < t->Num; ++i)
|
||||
{
|
||||
WGK *wgk = LIST_DATA(c->WgkList, i);
|
||||
WGK *rpc_wgk = &t->Wgks[i];
|
||||
|
||||
StrCpy(rpc_wgk->Key, sizeof(rpc_wgk->Key), wgk->Key);
|
||||
StrCpy(rpc_wgk->Hub, sizeof(rpc_wgk->Hub), wgk->Hub);
|
||||
StrCpy(rpc_wgk->User, sizeof(rpc_wgk->User), wgk->User);
|
||||
}
|
||||
}
|
||||
UnlockList(c->WgkList);
|
||||
|
||||
return ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
// Get status of connection to cluster controller
|
||||
UINT StGetFarmConnectionStatus(ADMIN *a, RPC_FARM_CONNECTION_STATUS *t)
|
||||
{
|
||||
@@ -10021,6 +10171,8 @@ UINT StGetProtoOptions(ADMIN *a, RPC_PROTO_OPTIONS *t)
|
||||
UINT ret = ERR_NO_ERROR;
|
||||
LIST *options;
|
||||
|
||||
SERVER_ADMIN_ONLY;
|
||||
|
||||
if (proto == NULL)
|
||||
{
|
||||
return ERR_NOT_SUPPORTED;
|
||||
@@ -12885,6 +13037,8 @@ void InRpcHubOption(RPC_HUB_OPTION *t, PACK *p)
|
||||
}
|
||||
|
||||
Zero(t, sizeof(RPC_HUB_OPTION));
|
||||
t->DefaultGateway = PackGetInt(p, "DefaultGateway");
|
||||
t->DefaultSubnet = PackGetInt(p, "DefaultSubnet");
|
||||
t->MaxSession = PackGetInt(p, "MaxSession");
|
||||
t->NoEnum = PackGetBool(p, "NoEnum");
|
||||
}
|
||||
@@ -12896,6 +13050,8 @@ void OutRpcHubOption(PACK *p, RPC_HUB_OPTION *t)
|
||||
return;
|
||||
}
|
||||
|
||||
PackAddInt(p, "DefaultGateway", t->DefaultGateway);
|
||||
PackAddInt(p, "DefaultSubnet", t->DefaultSubnet);
|
||||
PackAddInt(p, "MaxSession", t->MaxSession);
|
||||
PackAddBool(p, "NoEnum", t->NoEnum);
|
||||
}
|
||||
@@ -14455,6 +14611,64 @@ void FreeRpcKeyPair(RPC_KEY_PAIR *t)
|
||||
FreeK(t->Key);
|
||||
}
|
||||
|
||||
// RPC_WGK
|
||||
void InRpcWgk(RPC_WGK *t, PACK *p)
|
||||
{
|
||||
UINT i;
|
||||
// Validate arguments
|
||||
if (t == NULL || p == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Zero(t, sizeof(RPC_WGK));
|
||||
|
||||
t->Num = PackGetIndexCount(p, "Key");
|
||||
if (t->Num == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
t->Wgks = ZeroMalloc(sizeof(WGK) * t->Num);
|
||||
|
||||
for (i = 0; i < t->Num; ++i)
|
||||
{
|
||||
WGK *wgk = &t->Wgks[i];
|
||||
|
||||
PackGetStrEx(p, "Key", wgk->Key, sizeof(wgk->Key), i);
|
||||
PackGetStrEx(p, "Hub", wgk->Hub, sizeof(wgk->Hub), i);
|
||||
PackGetStrEx(p, "User", wgk->User, sizeof(wgk->User), i);
|
||||
}
|
||||
}
|
||||
void OutRpcWgk(PACK *p, RPC_WGK *t)
|
||||
{
|
||||
UINT i;
|
||||
// Validate arguments
|
||||
if (t == NULL || p == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < t->Num; ++i)
|
||||
{
|
||||
WGK *wgk = &t->Wgks[i];
|
||||
|
||||
PackAddStrEx(p, "Key", wgk->Key, i, t->Num);
|
||||
PackAddStrEx(p, "Hub", wgk->Hub, i, t->Num);
|
||||
PackAddStrEx(p, "User", wgk->User, i, t->Num);
|
||||
}
|
||||
}
|
||||
void FreeRpcWgk(RPC_WGK *t)
|
||||
{
|
||||
// Validate arguments
|
||||
if (t == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Free(t->Wgks);
|
||||
}
|
||||
|
||||
// NODE_INFO
|
||||
void InRpcNodeInfo(NODE_INFO *t, PACK *p)
|
||||
{
|
||||
|
||||
@@ -226,9 +226,18 @@ struct RPC_KEY_PAIR
|
||||
UINT Flag1; // Flag1
|
||||
};
|
||||
|
||||
// WireGuard keys
|
||||
struct RPC_WGK
|
||||
{
|
||||
UINT Num; // Number of keys
|
||||
WGK *Wgks; // Keys
|
||||
};
|
||||
|
||||
// HUB option
|
||||
struct RPC_HUB_OPTION
|
||||
{
|
||||
UINT DefaultGateway; // Default gateway address
|
||||
UINT DefaultSubnet; // Default subnet mask
|
||||
UINT MaxSession; // Maximum number of sessions
|
||||
bool NoEnum; // Not listed
|
||||
};
|
||||
@@ -987,6 +996,9 @@ UINT StGetServerCert(ADMIN *a, RPC_KEY_PAIR *t);
|
||||
UINT StGetServerCipherList(ADMIN *a, RPC_STR *t);
|
||||
UINT StGetServerCipher(ADMIN *a, RPC_STR *t);
|
||||
UINT StSetServerCipher(ADMIN *a, RPC_STR *t);
|
||||
UINT StAddWgk(ADMIN *a, RPC_WGK *t);
|
||||
UINT StDeleteWgk(ADMIN *a, RPC_WGK *t);
|
||||
UINT StEnumWgk(ADMIN *a, RPC_WGK *t);
|
||||
UINT StCreateHub(ADMIN *a, RPC_CREATE_HUB *t);
|
||||
UINT StSetHub(ADMIN *a, RPC_CREATE_HUB *t);
|
||||
UINT StGetHub(ADMIN *a, RPC_CREATE_HUB *t);
|
||||
@@ -1135,6 +1147,9 @@ UINT ScGetServerCert(RPC *r, RPC_KEY_PAIR *t);
|
||||
UINT ScGetServerCipherList(RPC *r, RPC_STR *t);
|
||||
UINT ScGetServerCipher(RPC *r, RPC_STR *t);
|
||||
UINT ScSetServerCipher(RPC *r, RPC_STR *t);
|
||||
UINT ScAddWgk(RPC *r, RPC_WGK *t);
|
||||
UINT ScDeleteWgk(RPC *r, RPC_WGK *t);
|
||||
UINT ScEnumWgk(RPC *r, RPC_WGK *t);
|
||||
UINT ScCreateHub(RPC *r, RPC_CREATE_HUB *t);
|
||||
UINT ScSetHub(RPC *r, RPC_CREATE_HUB *t);
|
||||
UINT ScGetHub(RPC *r, RPC_CREATE_HUB *t);
|
||||
@@ -1392,6 +1407,9 @@ void OutRpcMemInfo(PACK *p, MEMINFO *t);
|
||||
void InRpcKeyPair(RPC_KEY_PAIR *t, PACK *p);
|
||||
void OutRpcKeyPair(PACK *p, RPC_KEY_PAIR *t);
|
||||
void FreeRpcKeyPair(RPC_KEY_PAIR *t);
|
||||
void InRpcWgk(RPC_WGK *t, PACK *p);
|
||||
void OutRpcWgk(PACK *p, RPC_WGK *t);
|
||||
void FreeRpcWgk(RPC_WGK *t);
|
||||
void InRpcAddAccess(RPC_ADD_ACCESS *t, PACK *p);
|
||||
void OutRpcAddAccess(PACK *p, RPC_ADD_ACCESS *t);
|
||||
void InRpcDeleteAccess(RPC_DELETE_ACCESS *t, PACK *p);
|
||||
|
||||
@@ -19,6 +19,28 @@ set_target_properties(cedar
|
||||
RUNTIME_OUTPUT_DIRECTORY "${BUILD_DIRECTORY}"
|
||||
)
|
||||
|
||||
cmake_host_system_information(RESULT HAS_SSE2 QUERY HAS_SSE2)
|
||||
|
||||
set(BLAKE2_SRC_PATH $<IF:$<BOOL:HAS_SSE2>,${TOP_DIRECTORY}/3rdparty/BLAKE2/sse,${TOP_DIRECTORY}/3rdparty/BLAKE2/ref>)
|
||||
|
||||
target_include_directories(cedar PUBLIC ${BLAKE2_SRC_PATH})
|
||||
target_sources(cedar PRIVATE "${BLAKE2_SRC_PATH}/blake2s.c")
|
||||
|
||||
if(VCPKG_TARGET_TRIPLET)
|
||||
find_package(unofficial-sodium CONFIG REQUIRED)
|
||||
target_link_libraries(cedar PUBLIC unofficial-sodium::sodium)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(SODIUM libsodium REQUIRED)
|
||||
target_include_directories(cedar PUBLIC ${SODIUM_INCLUDE_DIRS})
|
||||
if(NOT ("$ENV{TRAVIS_CPU_ARCH}" STREQUAL ppc64le))
|
||||
target_link_libraries(cedar PUBLIC $<IF:$<BOOL:SODIUM_LINK_LIBRARIES>,${SODIUM_LINK_LIBRARIES},${SODIUM_LIBRARIES}>)
|
||||
else()
|
||||
# TODO: investigate why on ppc64le the use of SODIUM_LINK_LIBRARIES causes undefined references to libsodium functions.
|
||||
target_link_libraries(cedar PUBLIC ${SODIUM_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(cedar
|
||||
PROPERTIES
|
||||
@@ -31,10 +53,10 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
find_library(LIB_READLINE readline)
|
||||
find_package(Curses REQUIRED)
|
||||
find_library(LIB_READLINE readline)
|
||||
|
||||
target_link_libraries(cedar PRIVATE ${LIB_READLINE} ${CURSES_LIBRARIES})
|
||||
target_link_libraries(cedar PRIVATE ${CURSES_LIBRARIES} ${LIB_READLINE})
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
target_link_libraries(cedar PRIVATE mayaqua pcap)
|
||||
|
||||
+12
-4
@@ -1094,12 +1094,13 @@ void CleanupCedar(CEDAR *c)
|
||||
WuFreeWebUI(c->WebUI);
|
||||
FreeCedarLayer3(c);
|
||||
|
||||
/*
|
||||
for (i = 0;i < LIST_NUM(c->HubList);i++)
|
||||
for (i = 0; i < LIST_NUM(c->WgkList); ++i)
|
||||
{
|
||||
HUB *h = LIST_DATA(c->HubList, i);
|
||||
WGK *wgk = LIST_DATA(c->WgkList, i);
|
||||
Free(wgk);
|
||||
}
|
||||
*/
|
||||
ReleaseList(c->WgkList);
|
||||
|
||||
for (i = 0;i < LIST_NUM(c->CaList);i++)
|
||||
{
|
||||
X *x = LIST_DATA(c->CaList, i);
|
||||
@@ -1491,6 +1492,7 @@ CEDAR *NewCedar(X *server_x, K *server_k)
|
||||
c->Traffic = NewTraffic();
|
||||
c->TrafficLock = NewLock();
|
||||
c->CaList = NewList(CompareCert);
|
||||
c->WgkList = NewList(CompareWgk);
|
||||
|
||||
c->TrafficDiffList = NewList(NULL);
|
||||
|
||||
@@ -1600,6 +1602,12 @@ void InitCedar()
|
||||
return;
|
||||
}
|
||||
|
||||
if (sodium_init() == -1)
|
||||
{
|
||||
Debug("InitCedar(): sodium_init() failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize protocol module
|
||||
InitProtocol();
|
||||
}
|
||||
|
||||
+5
-2
@@ -363,6 +363,7 @@
|
||||
#define AUTHTYPE_ROOTCERT 3 // Root certificate which is issued by trusted Certificate Authority
|
||||
#define AUTHTYPE_RADIUS 4 // Radius authentication
|
||||
#define AUTHTYPE_NT 5 // Windows NT authentication
|
||||
#define AUTHTYPE_WIREGUARD_KEY 97 // WireGuard public key authentication
|
||||
#define AUTHTYPE_OPENVPN_CERT 98 // TLS client certificate authentication
|
||||
#define AUTHTYPE_TICKET 99 // Ticket authentication
|
||||
|
||||
@@ -919,6 +920,7 @@ typedef struct CEDAR
|
||||
UINT Type; // Type
|
||||
LIST *ListenerList; // Listener list
|
||||
LIST *HubList; // HUB list
|
||||
LIST *WgkList; // WireGuard key list
|
||||
LIST *ConnectionList; // Negotiating connection list
|
||||
LIST *CaList; // List of CA
|
||||
volatile bool Halt; // Halt flag
|
||||
@@ -1028,8 +1030,6 @@ typedef struct CEDAR
|
||||
#include <Cedar/Command.h>
|
||||
// RPC over HTTP
|
||||
#include <Cedar/Wpc.h>
|
||||
// Layer-2/Layer-3 converter
|
||||
#include <Cedar/IPC.h>
|
||||
// Third party protocols
|
||||
#include <Cedar/Proto.h>
|
||||
#include <Cedar/Proto_IPsec.h>
|
||||
@@ -1041,6 +1041,9 @@ typedef struct CEDAR
|
||||
#include <Cedar/Proto_PPP.h>
|
||||
#include <Cedar/Proto_SSTP.h>
|
||||
#include <Cedar/Proto_Win7.h>
|
||||
#include <Cedar/Proto_WireGuard.h>
|
||||
// Layer-2/Layer-3 converter
|
||||
#include <Cedar/IPC.h>
|
||||
// UDP Acceleration
|
||||
#include <Cedar/UdpAccel.h>
|
||||
// DDNS Client
|
||||
|
||||
@@ -277,6 +277,7 @@ typedef struct HUB_SNAPSHOT HUB_SNAPSHOT;
|
||||
typedef struct SERVER_SNAPSHOT SERVER_SNAPSHOT;
|
||||
typedef struct SERVER_HUB_CREATE_HISTORY SERVER_HUB_CREATE_HISTORY;
|
||||
typedef struct OPENVPN_SSTP_CONFIG OPENVPN_SSTP_CONFIG;
|
||||
typedef struct WGK WGK;
|
||||
|
||||
// ==============================================================
|
||||
// Server Admin Tool
|
||||
@@ -299,6 +300,7 @@ typedef struct RPC_ENUM_FARM_ITEM RPC_ENUM_FARM_ITEM;
|
||||
typedef struct RPC_ENUM_FARM RPC_ENUM_FARM;
|
||||
typedef struct RPC_FARM_CONNECTION_STATUS RPC_FARM_CONNECTION_STATUS;
|
||||
typedef struct RPC_KEY_PAIR RPC_KEY_PAIR;
|
||||
typedef struct RPC_WGK RPC_WGK;
|
||||
typedef struct RPC_HUB_OPTION RPC_HUB_OPTION;
|
||||
typedef struct RPC_RADIUS RPC_RADIUS;
|
||||
typedef struct RPC_HUB RPC_HUB;
|
||||
|
||||
@@ -7483,6 +7483,9 @@ void PsMain(PS *ps)
|
||||
{"RouterTableDel", PsRouterTableDel},
|
||||
{"LogFileList", PsLogFileList},
|
||||
{"LogFileGet", PsLogFileGet},
|
||||
{"WgkAdd", PsWgkAdd},
|
||||
{"WgkDelete", PsWgkDelete},
|
||||
{"WgkEnum", PsWgkEnum},
|
||||
{"HubCreate", PsHubCreate},
|
||||
{"HubCreateDynamic", PsHubCreateDynamic},
|
||||
{"HubCreateStatic", PsHubCreateStatic},
|
||||
@@ -7493,6 +7496,7 @@ void PsMain(PS *ps)
|
||||
{"Hub", PsHub},
|
||||
{"Online", PsOnline},
|
||||
{"Offline", PsOffline},
|
||||
{"SetStaticNetwork", PsSetStaticNetwork},
|
||||
{"SetMaxSession", PsSetMaxSession},
|
||||
{"SetHubPassword", PsSetHubPassword},
|
||||
{"SetEnumAllow", PsSetEnumAllow},
|
||||
@@ -10561,6 +10565,137 @@ UINT PsLogFileGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Add a WireGuard key (TODO: ability add multiple keys in a single call)
|
||||
UINT PsWgkAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
{
|
||||
PS *ps = (PS *)param;
|
||||
RPC_WGK t;
|
||||
UINT ret;
|
||||
LIST *o;
|
||||
PARAM args[] =
|
||||
{
|
||||
{"[key]", CmdPrompt, _UU("CMD_WgkAdd_Prompt_[key]"), CmdEvalNotEmpty, NULL},
|
||||
{"HUB", CmdPrompt, _UU("CMD_WgkAdd_Prompt_HUB"), NULL, NULL},
|
||||
{"USER", CmdPrompt, _UU("CMD_WgkAdd_Prompt_USER"), NULL, NULL}
|
||||
};
|
||||
|
||||
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
|
||||
if (o == NULL)
|
||||
{
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Zero(&t, sizeof(t));
|
||||
t.Num = 1;
|
||||
t.Wgks = ZeroMalloc(sizeof(WGK));
|
||||
|
||||
StrCpy(t.Wgks[0].Key, sizeof(t.Wgks[0].Key), GetParamStr(o, "[key]"));
|
||||
StrCpy(t.Wgks[0].Hub, sizeof(t.Wgks[0].Hub), GetParamStr(o, "HUB"));
|
||||
StrCpy(t.Wgks[0].User, sizeof(t.Wgks[0].User), GetParamStr(o, "USER"));
|
||||
|
||||
FreeParamValueList(o);
|
||||
|
||||
ret = ScAddWgk(ps->Rpc, &t);
|
||||
if (ret != ERR_NO_ERROR)
|
||||
{
|
||||
CmdPrintError(c, ret);
|
||||
}
|
||||
|
||||
FreeRpcWgk(&t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Delete a WireGuard key (TODO: ability to delete multiple keys in a single call)
|
||||
UINT PsWgkDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
{
|
||||
PS *ps = (PS *)param;
|
||||
RPC_WGK t;
|
||||
UINT ret;
|
||||
LIST *o;
|
||||
PARAM args[] =
|
||||
{
|
||||
{"[key]", CmdPrompt, _UU("CMD_WgkDelete_Prompt_[key]"), CmdEvalNotEmpty, NULL},
|
||||
};
|
||||
|
||||
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
|
||||
if (o == NULL)
|
||||
{
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Zero(&t, sizeof(t));
|
||||
t.Num = 1;
|
||||
t.Wgks = ZeroMalloc(sizeof(WGK));
|
||||
|
||||
StrCpy(t.Wgks[0].Key, sizeof(t.Wgks[0].Key), GetParamStr(o, "[key]"));
|
||||
|
||||
FreeParamValueList(o);
|
||||
|
||||
ret = ScDeleteWgk(ps->Rpc, &t);
|
||||
if (ret != ERR_NO_ERROR)
|
||||
{
|
||||
CmdPrintError(c, ret);
|
||||
}
|
||||
|
||||
FreeRpcWgk(&t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// List the WireGuard keys
|
||||
UINT PsWgkEnum(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
{
|
||||
UINT ret = ERR_NO_ERROR;
|
||||
PS *ps = (PS *)param;
|
||||
RPC_WGK t;
|
||||
LIST *o;
|
||||
|
||||
o = ParseCommandList(c, cmd_name, str, NULL, 0);
|
||||
if (o == NULL)
|
||||
{
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Zero(&t, sizeof(t));
|
||||
|
||||
ret = ScEnumWgk(ps->Rpc, &t);
|
||||
if (ret == ERR_NO_ERROR)
|
||||
{
|
||||
UINT i;
|
||||
CT *ct = CtNew();
|
||||
CtInsertColumn(ct, _UU("CMD_WgkEnum_Column_Key"), false);
|
||||
CtInsertColumn(ct, _UU("CMD_WgkEnum_Column_Hub"), false);
|
||||
CtInsertColumn(ct, _UU("CMD_WgkEnum_Column_User"), false);
|
||||
|
||||
for (i = 0; i < t.Num; ++i)
|
||||
{
|
||||
const WGK *wgk = &t.Wgks[i];
|
||||
wchar_t *key, *hub, *user;
|
||||
|
||||
key = CopyStrToUni(wgk->Key);
|
||||
hub = CopyStrToUni(wgk->Hub);
|
||||
user = CopyStrToUni(wgk->User);
|
||||
|
||||
CtInsert(ct, key, hub, user);
|
||||
|
||||
Free(key);
|
||||
Free(hub);
|
||||
Free(user);
|
||||
}
|
||||
|
||||
CtFree(ct, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
CmdPrintError(c, ret);
|
||||
}
|
||||
|
||||
FreeRpcWgk(&t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Create a New Virtual HUB
|
||||
UINT PsHubCreate(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
{
|
||||
@@ -11143,6 +11278,53 @@ UINT PsOffline(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the static IPv4 network parameters for the Virtual HUB
|
||||
UINT PsSetStaticNetwork(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
{
|
||||
LIST *o;
|
||||
PS *ps = (PS *)param;
|
||||
UINT ret = 0;
|
||||
RPC_CREATE_HUB t;
|
||||
PARAM args[] =
|
||||
{
|
||||
{"GATEWAY", CmdPrompt, _UU("CMD_SetStaticNetwork_Prompt_GATEWAY"), CmdEvalIp, NULL},
|
||||
{"SUBNET", CmdPrompt, _UU("CMD_SetStaticNetwork_Prompt_SUBNET"), CmdEvalIp, NULL}
|
||||
};
|
||||
|
||||
if (ps->HubName == NULL)
|
||||
{
|
||||
c->Write(c, _UU("CMD_Hub_Not_Selected"));
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
|
||||
if (o == NULL)
|
||||
{
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Zero(&t, sizeof(t));
|
||||
StrCpy(t.HubName, sizeof(t.HubName), ps->HubName);
|
||||
ret = ScGetHub(ps->Rpc, &t);
|
||||
if (ret != ERR_NO_ERROR)
|
||||
{
|
||||
goto FINAL;
|
||||
}
|
||||
|
||||
t.HubOption.DefaultGateway = StrToIP32(GetParamStr(o, "GATEWAY"));
|
||||
t.HubOption.DefaultSubnet = StrToIP32(GetParamStr(o, "SUBNET"));
|
||||
|
||||
ret = ScSetHub(ps->Rpc, &t);
|
||||
FINAL:
|
||||
if (ret != ERR_NO_ERROR)
|
||||
{
|
||||
CmdPrintError(c, ret);
|
||||
}
|
||||
|
||||
FreeParamValueList(o);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set the maximum number of concurrent connecting sessions of the Virtual HUB
|
||||
UINT PsSetMaxSession(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
{
|
||||
@@ -11420,6 +11602,12 @@ UINT PsOptionsGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
|
||||
CtInsert(ct, _UU("CMD_OptionsGet_TYPE"), GetHubTypeStr(t.HubType));
|
||||
|
||||
IPToUniStr32(tmp, sizeof(tmp), t.HubOption.DefaultGateway);
|
||||
CtInsert(ct, _UU("CMD_OptionsGet_GATEWAY"), tmp);
|
||||
|
||||
IPToUniStr32(tmp, sizeof(tmp), t.HubOption.DefaultSubnet);
|
||||
CtInsert(ct, _UU("CMD_OptionsGet_SUBNET"), tmp);
|
||||
|
||||
CtFree(ct, c);
|
||||
}
|
||||
|
||||
|
||||
@@ -446,6 +446,9 @@ UINT PsRouterTableAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsRouterTableDel(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsLogFileList(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsLogFileGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsWgkAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsWgkDelete(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsWgkEnum(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsHubCreate(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsHubCreateDynamic(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsHubCreateStatic(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
@@ -456,6 +459,7 @@ UINT PsHubList(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsHub(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsOnline(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsOffline(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsSetStaticNetwork(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsSetMaxSession(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsSetHubPassword(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
UINT PsSetEnumAllow(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
|
||||
|
||||
@@ -116,6 +116,8 @@ struct HUB_PA
|
||||
struct HUB_OPTION
|
||||
{
|
||||
// Standard options
|
||||
UINT DefaultGateway; // Used in IPC when DHCP cannot be used (e.g. WireGuard sessions)
|
||||
UINT DefaultSubnet; // Used in IPC when DHCP cannot be used (e.g. WireGuard sessions)
|
||||
UINT MaxSession; // Maximum number of simultaneous connections
|
||||
bool NoEnum; // Excluded from the enumeration
|
||||
// Advanced options
|
||||
|
||||
+16
-7
@@ -226,8 +226,8 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
|
||||
}
|
||||
|
||||
ipc = NewIPC(cedar, param->ClientName, param->Postfix, param->HubName,
|
||||
param->UserName, param->Password, error_code, ¶m->ClientIp,
|
||||
param->ClientPort, ¶m->ServerIp, param->ServerPort,
|
||||
param->UserName, param->Password, param->WgKey, error_code,
|
||||
¶m->ClientIp, param->ClientPort, ¶m->ServerIp, param->ServerPort,
|
||||
param->ClientHostname, param->CryptName,
|
||||
param->BridgeMode, param->Mss, NULL, param->ClientCertificate, param->Layer);
|
||||
|
||||
@@ -235,13 +235,14 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
|
||||
}
|
||||
|
||||
// Start a new IPC connection
|
||||
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
|
||||
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, char *wg_key,
|
||||
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
|
||||
char *client_hostname, char *crypt_name,
|
||||
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
|
||||
UINT layer)
|
||||
{
|
||||
IPC *ipc;
|
||||
HUB *hub;
|
||||
UINT dummy_int = 0;
|
||||
SOCK *a;
|
||||
SOCK *s;
|
||||
@@ -297,9 +298,6 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
|
||||
ipc->FlushList = NewTubeFlushList();
|
||||
|
||||
StrCpy(ipc->ClientHostname, sizeof(ipc->ClientHostname), client_hostname);
|
||||
StrCpy(ipc->HubName, sizeof(ipc->HubName), hubname);
|
||||
StrCpy(ipc->UserName, sizeof(ipc->UserName), username);
|
||||
StrCpy(ipc->Password, sizeof(ipc->Password), password);
|
||||
|
||||
// Connect the in-process socket
|
||||
s = ConnectInProc(a, client_ip, client_port, server_ip, server_port);
|
||||
@@ -339,7 +337,11 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
|
||||
FreePack(p);
|
||||
|
||||
// Upload the authentication data
|
||||
if (client_certificate != NULL)
|
||||
if (IsEmptyStr(wg_key) == false)
|
||||
{
|
||||
p = PackLoginWithWireGuardKey(wg_key);
|
||||
}
|
||||
else if (client_certificate != NULL)
|
||||
{
|
||||
p = PackLoginWithOpenVPNCertificate(hubname, username, client_certificate);
|
||||
}
|
||||
@@ -466,6 +468,13 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
|
||||
PackGetStr(p, "IpcHubName", ipc->HubName, sizeof(ipc->HubName));
|
||||
Debug("IPC Hub Name: %s\n", ipc->HubName);
|
||||
|
||||
hub = GetHub(cedar, ipc->HubName);
|
||||
if (hub != NULL)
|
||||
{
|
||||
UINTToIP(&ipc->DefaultGateway, hub->Option->DefaultGateway);
|
||||
UINTToIP(&ipc->SubnetMask, hub->Option->DefaultSubnet);
|
||||
}
|
||||
|
||||
MacToStr(macstr, sizeof(macstr), ipc->MacAddress);
|
||||
|
||||
Debug("IPC: Session = %s, Connection = %s, Mac = %s\n", ipc->SessionName, ipc->ConnectionName, macstr);
|
||||
|
||||
+2
-3
@@ -75,6 +75,7 @@ struct IPC_PARAM
|
||||
char HubName[MAX_HUBNAME_LEN + 1];
|
||||
char UserName[MAX_USERNAME_LEN + 1];
|
||||
char Password[MAX_PASSWORD_LEN + 1];
|
||||
char WgKey[WG_KEY_BASE64_SIZE];
|
||||
IP ClientIp;
|
||||
UINT ClientPort;
|
||||
IP ServerIp;
|
||||
@@ -119,8 +120,6 @@ struct IPC
|
||||
{
|
||||
CEDAR *Cedar;
|
||||
char HubName[MAX_HUBNAME_LEN + 1];
|
||||
char UserName[MAX_USERNAME_LEN + 1];
|
||||
char Password[MAX_PASSWORD_LEN + 1];
|
||||
char ClientHostname[MAX_SIZE];
|
||||
UCHAR random[SHA1_SIZE];
|
||||
char SessionName[MAX_SESSION_NAME_LEN + 1];
|
||||
@@ -173,7 +172,7 @@ struct IPC_IPV6_ROUTER_ADVERTISEMENT
|
||||
UCHAR RouterLinkLayerAddress[6];
|
||||
};
|
||||
|
||||
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
|
||||
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, char *wg_key,
|
||||
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
|
||||
char *client_hostname, char *crypt_name,
|
||||
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
|
||||
|
||||
+3
-1
@@ -213,6 +213,8 @@ PROTO *ProtoNew(CEDAR *cedar)
|
||||
|
||||
AddRef(cedar->ref);
|
||||
|
||||
// WireGuard
|
||||
Add(proto->Containers, ProtoContainerNew(WgsGetProtoImpl()));
|
||||
// OpenVPN
|
||||
Add(proto->Containers, ProtoContainerNew(OvsGetProtoImpl()));
|
||||
// SSTP
|
||||
@@ -291,7 +293,7 @@ PROTO_CONTAINER *ProtoContainerNew(const PROTO_IMPL *impl)
|
||||
option->Bool = impl_option->Bool;
|
||||
break;
|
||||
case PROTO_OPTION_STRING:
|
||||
option->String = CopyStr(impl_option->String);
|
||||
option->String = impl_option->String != NULL ? CopyStr(impl_option->String) : impl->OptionStringValue(option->Name);
|
||||
break;
|
||||
default:
|
||||
Debug("ProtoContainerNew(): unhandled option type %u!\n", impl_option->Type);
|
||||
|
||||
+2
-1
@@ -46,9 +46,10 @@ typedef struct PROTO_IMPL
|
||||
{
|
||||
const char *(*Name)();
|
||||
const PROTO_OPTION *(*Options)();
|
||||
char *(*OptionStringValue)(const char *name);
|
||||
bool (*Init)(void **param, const LIST *options, CEDAR *cedar, INTERRUPT_MANAGER *im, SOCK_EVENT *se, const char *cipher, const char *hostname);
|
||||
void (*Free)(void *param);
|
||||
bool (*IsPacketForMe)(const PROTO_MODE mode, const UCHAR *data, const UINT size);
|
||||
bool (*IsPacketForMe)(const PROTO_MODE mode, const void *data, const UINT size);
|
||||
bool (*ProcessData)(void *param, TCP_RAW_DATA *in, FIFO *out);
|
||||
bool (*ProcessDatagrams)(void *param, LIST *in, LIST *out);
|
||||
} PROTO_IMPL;
|
||||
|
||||
@@ -59,7 +59,7 @@ void EtherIPIpcConnectThread(THREAD *t, void *p)
|
||||
EtherIPLog(s, "LE_START_IPC", id.HubName, id.UserName, mss);
|
||||
ipc = NewIPC(s->Cedar, client_name,
|
||||
(s->L2TPv3 ? ETHERIP_L2TPV3_POSTFIX : ETHERIP_POSTFIX),
|
||||
id.HubName, id.UserName, id.Password,
|
||||
id.HubName, id.UserName, id.Password, NULL,
|
||||
&error_code,
|
||||
&s->ClientIP, s->ClientPort,
|
||||
&s->ServerIP, s->ServerPort,
|
||||
|
||||
@@ -20,6 +20,7 @@ const PROTO_IMPL *OvsGetProtoImpl()
|
||||
{
|
||||
OvsName,
|
||||
OvsOptions,
|
||||
NULL,
|
||||
OvsInit,
|
||||
OvsFree,
|
||||
OvsIsPacketForMe,
|
||||
@@ -69,16 +70,17 @@ void OvsFree(void *param)
|
||||
}
|
||||
|
||||
// Check whether it's an OpenVPN packet
|
||||
bool OvsIsPacketForMe(const PROTO_MODE mode, const UCHAR *data, const UINT size)
|
||||
bool OvsIsPacketForMe(const PROTO_MODE mode, const void *data, const UINT size)
|
||||
{
|
||||
if (data == NULL || size < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode == PROTO_MODE_TCP)
|
||||
{
|
||||
if (data == NULL || size < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data[0] == 0x00 && data[1] == 0x0E)
|
||||
const UCHAR *raw = data;
|
||||
if (raw[0] == 0x00 && raw[1] == 0x0E)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -215,11 +215,9 @@ const char *OvsName();
|
||||
const PROTO_OPTION *OvsOptions();
|
||||
bool OvsInit(void **param, const LIST *options, CEDAR *cedar, INTERRUPT_MANAGER *im, SOCK_EVENT *se, const char *cipher, const char *hostname);
|
||||
void OvsFree(void *param);
|
||||
bool OvsIsPacketForMe(const PROTO_MODE mode, const UCHAR *data, const UINT size);
|
||||
bool OvsIsPacketForMe(const PROTO_MODE mode, const void *data, const UINT size);
|
||||
bool OvsProcessData(void *param, TCP_RAW_DATA *in, FIFO *out);
|
||||
bool OvsProcessDatagrams(void *param, LIST *in, LIST *out);
|
||||
bool OvsIsOk(void *param);
|
||||
UINT OvsEstablishedSessions(void *param);
|
||||
|
||||
OPENVPN_SERVER *NewOpenVpnServer(const LIST *options, CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOCK_EVENT *sock_event);
|
||||
void FreeOpenVpnServer(OPENVPN_SERVER *s);
|
||||
|
||||
@@ -1519,7 +1519,7 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
||||
// Attempt to connect with IPC
|
||||
UINT error_code;
|
||||
|
||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
|
||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, NULL,
|
||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, NULL,
|
||||
IPC_LAYER_3);
|
||||
@@ -2844,7 +2844,7 @@ bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp)
|
||||
else if (p->Ipc == NULL)
|
||||
{
|
||||
Debug("MSCHAPv2 creating IPC\n");
|
||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
|
||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, NULL,
|
||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL,
|
||||
+ IPC_LAYER_3);
|
||||
@@ -3252,7 +3252,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
||||
|
||||
PPPParseUsername(p->Cedar, p->Eap_Identity, &d);
|
||||
|
||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, d.HubName, d.UserName, "",
|
||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, d.HubName, d.UserName, "", NULL,
|
||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, p->Eap_TlsCtx.ClientCert.X,
|
||||
IPC_LAYER_3);
|
||||
|
||||
@@ -13,6 +13,7 @@ const PROTO_IMPL *SstpGetProtoImpl()
|
||||
{
|
||||
SstpName,
|
||||
SstpOptions,
|
||||
NULL,
|
||||
SstpInit,
|
||||
SstpFree,
|
||||
NULL,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,209 @@
|
||||
#ifndef PROTO_WIREGUARD_H
|
||||
#define PROTO_WIREGUARD_H
|
||||
|
||||
#include <sodium.h>
|
||||
|
||||
#define WG_IPC_POSTFIX "WIREGUARD"
|
||||
|
||||
#define WG_CIPHER "ChaCha20-Poly1305"
|
||||
|
||||
#define WG_CONSTRUCTION "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"
|
||||
#define WG_IDENTIFIER "WireGuard v1 zx2c4 Jason@zx2c4.com"
|
||||
#define WG_LABEL_COOKIE "cookie--"
|
||||
#define WG_LABEL_MAC1 "mac1----"
|
||||
|
||||
#define WG_MAX_INITIATIONS_PER_SECOND 50
|
||||
|
||||
#define WG_KEEPALIVE_TIMEOUT 10000 // 10 seconds
|
||||
#define WG_INITIATION_GIVEUP 30000 // 30 seconds
|
||||
|
||||
#define WG_REJECT_AFTER_TIME 180000 // 180 seconds
|
||||
#define WG_REJECT_AFTER_MESSAGES (UINT64_MAX - 16 - 1)
|
||||
|
||||
#define WG_KEY_SIZE crypto_aead_chacha20poly1305_ietf_KEYBYTES
|
||||
#define WG_IV_SIZE crypto_aead_chacha20poly1305_ietf_NPUBBYTES
|
||||
#define WG_TAG_SIZE crypto_aead_chacha20poly1305_ietf_ABYTES
|
||||
|
||||
#define WG_COOKIE_IV_SIZE crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
|
||||
#define WG_COOKIE_TAG_SIZE crypto_aead_xchacha20poly1305_ietf_ABYTES
|
||||
|
||||
#define WG_HASH_SIZE 32
|
||||
#define WG_BLOCK_SIZE 16
|
||||
#define WG_COOKIE_SIZE 16
|
||||
#define WG_TIMESTAMP_SIZE (sizeof(UINT64) + sizeof(UINT))
|
||||
|
||||
#define WG_KEY_BASE64_SIZE (sodium_base64_ENCODED_LEN(WG_KEY_SIZE, sodium_base64_VARIANT_ORIGINAL))
|
||||
|
||||
#define WG_AEAD_SIZE(plain_size) (plain_size + WG_TAG_SIZE)
|
||||
#define WG_PLAIN_SIZE(aead_size) (aead_size - WG_TAG_SIZE)
|
||||
|
||||
// RFC 6479
|
||||
#define WG_REPLAY_WINDOW_SIZE 1024
|
||||
#define WG_REPLAY_BITMAP_SIZE (WG_REPLAY_WINDOW_SIZE / (sizeof(int) * 8))
|
||||
#define WG_REPLAY_BITMAP_INDEX_MASK (WG_REPLAY_BITMAP_SIZE - 1)
|
||||
#define WG_REPLAY_REDUNDANT_BIT_SHIFTS 5
|
||||
#define WG_REPLAY_REDUNDANT_BITS (1 << WG_REPLAY_REDUNDANT_BIT_SHIFTS)
|
||||
#define WG_REPLAY_BITMAP_LOC_MASK (WG_REPLAY_REDUNDANT_BITS - 1)
|
||||
|
||||
typedef enum WG_MSG_TYPE
|
||||
{
|
||||
WG_MSG_INVALID = 0,
|
||||
WG_MSG_HANDSHAKE_INIT,
|
||||
WG_MSG_HANDSHAKE_REPLY,
|
||||
WG_MSG_HANDSHAKE_COOKIE,
|
||||
WG_MSG_TRANSPORT_DATA
|
||||
} WG_MSG_TYPE;
|
||||
|
||||
typedef enum WG_KEYPAIR_STATE
|
||||
{
|
||||
WG_KEYPAIR_INVALID = 0,
|
||||
WG_KEYPAIR_INITIATED,
|
||||
WG_KEYPAIR_CONFIRMED
|
||||
} WG_KEYPAIR_STATE;
|
||||
|
||||
typedef struct WG_HEADER
|
||||
{
|
||||
BYTE Type;
|
||||
BYTE Reserved[3];
|
||||
} WG_HEADER;
|
||||
|
||||
typedef struct WG_COMMON
|
||||
{
|
||||
WG_HEADER Header;
|
||||
UINT Index;
|
||||
} WG_COMMON;
|
||||
|
||||
typedef struct WG_MACS
|
||||
{
|
||||
BYTE Mac1[WG_COOKIE_SIZE];
|
||||
BYTE Mac2[WG_COOKIE_SIZE];
|
||||
} WG_MACS;
|
||||
|
||||
typedef struct WG_HANDSHAKE_INIT
|
||||
{
|
||||
WG_HEADER Header;
|
||||
UINT SenderIndex;
|
||||
BYTE UnencryptedEphemeral[WG_KEY_SIZE];
|
||||
BYTE EncryptedStatic[WG_AEAD_SIZE(WG_KEY_SIZE)];
|
||||
BYTE EncryptedTimestamp[WG_AEAD_SIZE(WG_TIMESTAMP_SIZE)];
|
||||
WG_MACS Macs;
|
||||
} WG_HANDSHAKE_INIT;
|
||||
|
||||
typedef struct WG_HANDSHAKE_REPLY
|
||||
{
|
||||
WG_HEADER Header;
|
||||
UINT SenderIndex;
|
||||
UINT ReceiverIndex;
|
||||
BYTE UnencryptedEphemeral[WG_KEY_SIZE];
|
||||
BYTE EncryptedNothing[WG_AEAD_SIZE(0)];
|
||||
WG_MACS Macs;
|
||||
} WG_HANDSHAKE_REPLY;
|
||||
|
||||
typedef struct WG_COOKIE_REPLY
|
||||
{
|
||||
WG_HEADER Header;
|
||||
UINT ReceiverIndex;
|
||||
BYTE Nonce[WG_COOKIE_IV_SIZE];
|
||||
BYTE EncryptedCookie[WG_COOKIE_SIZE + WG_COOKIE_TAG_SIZE];
|
||||
} WG_COOKIE_REPLY;
|
||||
|
||||
typedef struct WG_TRANSPORT_DATA
|
||||
{
|
||||
WG_HEADER Header;
|
||||
UINT ReceiverIndex;
|
||||
UINT64 Counter;
|
||||
BYTE EncapsulatedPacket[];
|
||||
} WG_TRANSPORT_DATA;
|
||||
|
||||
typedef struct WG_KEYPAIR
|
||||
{
|
||||
WG_KEYPAIR_STATE State;
|
||||
UINT64 CreationTime;
|
||||
UINT IndexLocal;
|
||||
UINT IndexRemote;
|
||||
UINT64 CounterLocal;
|
||||
UINT64 CounterRemote;
|
||||
BYTE KeyLocal[WG_KEY_SIZE];
|
||||
BYTE KeyRemote[WG_KEY_SIZE];
|
||||
UINT64 ReplayWindow[WG_REPLAY_WINDOW_SIZE];
|
||||
} WG_KEYPAIR;
|
||||
|
||||
typedef struct WG_KEYPAIRS
|
||||
{
|
||||
WG_KEYPAIR *Current;
|
||||
WG_KEYPAIR *Next;
|
||||
WG_KEYPAIR *Previous;
|
||||
} WG_KEYPAIRS;
|
||||
|
||||
typedef struct WG_SESSION
|
||||
{
|
||||
WG_KEYPAIRS Keypairs;
|
||||
IPC *IPC;
|
||||
IP IPLocal;
|
||||
IP IPRemote;
|
||||
USHORT PortLocal;
|
||||
USHORT PortRemote;
|
||||
UINT64 LastInitiationReceived;
|
||||
UINT64 LastDataReceived;
|
||||
UINT64 LastDataSent;
|
||||
BYTE StaticRemote[WG_KEY_SIZE];
|
||||
BYTE LastTimestamp[WG_TIMESTAMP_SIZE];
|
||||
BYTE Hash[WG_HASH_SIZE];
|
||||
BYTE ChainingKey[WG_HASH_SIZE];
|
||||
BYTE PrecomputedStaticStatic[WG_KEY_SIZE];
|
||||
} WG_SESSION;
|
||||
|
||||
typedef struct WG_SERVER
|
||||
{
|
||||
UINT64 Now;
|
||||
UINT64 CreationTime;
|
||||
WG_SESSION Session;
|
||||
CEDAR *Cedar;
|
||||
SOCK_EVENT *SockEvent;
|
||||
INTERRUPT_MANAGER *InterruptManager;
|
||||
BYTE PresharedKey[WG_KEY_SIZE];
|
||||
BYTE StaticPublic[WG_KEY_SIZE];
|
||||
BYTE StaticPrivate[WG_KEY_SIZE];
|
||||
BYTE HandshakeInitHash[WG_HASH_SIZE];
|
||||
BYTE HandshakeInitChainingKey[WG_HASH_SIZE];
|
||||
} WG_SERVER;
|
||||
|
||||
const PROTO_IMPL *WgsGetProtoImpl();
|
||||
const char *WgsName();
|
||||
const PROTO_OPTION *WgsOptions();
|
||||
char *WgsOptionStringValue(const char *name);
|
||||
bool WgsInit(void **param, const LIST *options, CEDAR *cedar, INTERRUPT_MANAGER *im, SOCK_EVENT *se, const char *cipher, const char *hostname);
|
||||
void WgsFree(void *param);
|
||||
bool WgsIsPacketForMe(const PROTO_MODE mode, const void *data, const UINT size);
|
||||
bool WgsProcessDatagrams(void *param, LIST *in, LIST *out);
|
||||
|
||||
void WgsLog(const WG_SERVER *server, const char *name, ...);
|
||||
|
||||
WG_MSG_TYPE WgsDetectMessageType(const void *data, const UINT size);
|
||||
|
||||
UINT WgsMSS(const WG_SESSION *session);
|
||||
|
||||
IPC *WgsIPCNew(WG_SERVER *server);
|
||||
|
||||
WG_KEYPAIR *WgsProcessHandshakeInit(WG_SERVER *server, const WG_HANDSHAKE_INIT *init, BYTE *ephemeral_remote);
|
||||
WG_HANDSHAKE_REPLY *WgsCreateHandshakeReply(WG_SERVER *server, WG_KEYPAIR *keypair, const BYTE *ephemeral_remote);
|
||||
|
||||
bool WgsProcessTransportData(WG_SERVER *server, WG_TRANSPORT_DATA *data, const UINT size);
|
||||
WG_TRANSPORT_DATA *WgsCreateTransportData(WG_SERVER *server, const void *data, const UINT size, UINT *final_size);
|
||||
|
||||
bool WgsIsInReplayWindow(const WG_KEYPAIR *keypair, const UINT64 counter);
|
||||
void WgsUpdateReplayWindow(WG_KEYPAIR *keypair, const UINT64 counter);
|
||||
|
||||
UINT WgsEncryptData(void *key, const UINT64 counter, void *dst, const void *src, const UINT src_size);
|
||||
UINT WgsDecryptData(void *key, const UINT64 counter, void *dst, const void *src, const UINT src_size);
|
||||
|
||||
bool WgsEncryptWithHash(void *dst, const void *src, const UINT src_size, BYTE *hash, const BYTE *key);
|
||||
bool WgsDecryptWithHash(void *dst, const void *src, const UINT src_size, BYTE *hash, const BYTE *key);
|
||||
|
||||
void WgsEphemeral(BYTE *ephemeral_dst, const BYTE *ephemeral_src, BYTE *chaining_key, BYTE *hash);
|
||||
void WgsHKDF(BYTE *dst_1, BYTE *dst_2, BYTE *dst_3, const BYTE *data, const UINT data_size, const BYTE *chaining_key);
|
||||
|
||||
void WgsMixHash(void *dst, const void *src, const UINT size);
|
||||
bool WgsMixDh(BYTE *chaining_key, BYTE *key, const BYTE *priv, const BYTE *pub);
|
||||
|
||||
#endif
|
||||
+88
-34
@@ -1330,12 +1330,45 @@ bool ServerAccept(CONNECTION *c)
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Login
|
||||
if (GetHubnameAndUsernameFromPack(p, username, sizeof(username), hubname, sizeof(hubname)) == false)
|
||||
// Get authentication method and initiate login process
|
||||
authtype = GetAuthTypeFromPack(p);
|
||||
if (authtype == AUTHTYPE_WIREGUARD_KEY)
|
||||
{
|
||||
WGK *wgk, tmp;
|
||||
bool ok = false;
|
||||
|
||||
if (PackGetStr(p, "key", tmp.Key, sizeof(tmp.Key)) == false)
|
||||
{
|
||||
FreePack(p);
|
||||
c->Err = ERR_PROTOCOL_ERROR;
|
||||
error_detail = "GetWireGuardKeyFromPack";
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
LockList(c->Cedar->WgkList);
|
||||
{
|
||||
wgk = Search(c->Cedar->WgkList, &tmp);
|
||||
if (wgk != NULL)
|
||||
{
|
||||
ok = true;
|
||||
StrCpy(hubname, sizeof(hubname), wgk->Hub);
|
||||
StrCpy(username, sizeof(username), wgk->User);
|
||||
StrCpy(node.HubName, sizeof(node.HubName), hubname);
|
||||
}
|
||||
}
|
||||
UnlockList(c->Cedar->WgkList);
|
||||
|
||||
if (ok == false)
|
||||
{
|
||||
FreePack(p);
|
||||
c->Err = ERR_AUTH_FAILED;
|
||||
SLog(c->Cedar, "LS_WG_KEY_NOT_FOUND", c->Name, hubname);
|
||||
error_detail = "ERR_AUTH_FAILED";
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
else if (GetHubnameAndUsernameFromPack(p, username, sizeof(username), hubname, sizeof(hubname)) == false)
|
||||
{
|
||||
// Protocol error
|
||||
FreePack(p);
|
||||
c->Err = ERR_PROTOCOL_ERROR;
|
||||
error_detail = "GetHubnameAndUsernameFromPack";
|
||||
@@ -1345,9 +1378,7 @@ bool ServerAccept(CONNECTION *c)
|
||||
if (farm_member)
|
||||
{
|
||||
bool ok = false;
|
||||
UINT authtype;
|
||||
|
||||
authtype = GetAuthTypeFromPack(p);
|
||||
if (StrCmpi(username, ADMINISTRATOR_USERNAME) == 0 &&
|
||||
authtype == AUTHTYPE_PASSWORD)
|
||||
{
|
||||
@@ -1600,9 +1631,6 @@ bool ServerAccept(CONNECTION *c)
|
||||
PackGetData(p, "unique_id", unique);
|
||||
}
|
||||
|
||||
// Get the authentication method
|
||||
authtype = GetAuthTypeFromPack(p);
|
||||
|
||||
if (1)
|
||||
{
|
||||
// Log
|
||||
@@ -1622,12 +1650,15 @@ bool ServerAccept(CONNECTION *c)
|
||||
case CLIENT_AUTHTYPE_CERT:
|
||||
authtype_str = _UU("LH_AUTH_CERT");
|
||||
break;
|
||||
case AUTHTYPE_TICKET:
|
||||
authtype_str = _UU("LH_AUTH_TICKET");
|
||||
case AUTHTYPE_WIREGUARD_KEY:
|
||||
authtype_str = _UU("LH_AUTH_WIREGUARD_KEY");
|
||||
break;
|
||||
case AUTHTYPE_OPENVPN_CERT:
|
||||
authtype_str = _UU("LH_AUTH_OPENVPN_CERT");
|
||||
break;
|
||||
case AUTHTYPE_TICKET:
|
||||
authtype_str = _UU("LH_AUTH_TICKET");
|
||||
break;
|
||||
}
|
||||
IPToStr(ip1, sizeof(ip1), &c->FirstSock->RemoteIP);
|
||||
IPToStr(ip2, sizeof(ip2), &c->FirstSock->LocalIP);
|
||||
@@ -1640,7 +1671,6 @@ bool ServerAccept(CONNECTION *c)
|
||||
|
||||
// Attempt an anonymous authentication first
|
||||
auth_ret = SamAuthUserByAnonymous(hub, username);
|
||||
|
||||
if (auth_ret)
|
||||
{
|
||||
if (c->IsInProc)
|
||||
@@ -1734,8 +1764,6 @@ bool ServerAccept(CONNECTION *c)
|
||||
|
||||
if (auth_ret)
|
||||
{
|
||||
// User authentication success by anonymous authentication
|
||||
HLog(hub, "LH_AUTH_OK", c->Name, username);
|
||||
is_empty_password = true;
|
||||
}
|
||||
}
|
||||
@@ -1961,6 +1989,24 @@ bool ServerAccept(CONNECTION *c)
|
||||
}
|
||||
break;
|
||||
|
||||
case AUTHTYPE_WIREGUARD_KEY:
|
||||
// We already retrieved the hubname and username associated with the key.
|
||||
// Now we only have to verify that the user effectively exists.
|
||||
if (c->IsInProc)
|
||||
{
|
||||
auth_ret = SamIsUser(hub, username);
|
||||
}
|
||||
else
|
||||
{
|
||||
// WireGuard public key authentication cannot be used directly by external clients.
|
||||
Unlock(hub->lock);
|
||||
ReleaseHub(hub);
|
||||
FreePack(p);
|
||||
c->Err = ERR_AUTHTYPE_NOT_SUPPORTED;
|
||||
goto CLEANUP;
|
||||
}
|
||||
break;
|
||||
|
||||
case AUTHTYPE_OPENVPN_CERT:
|
||||
// For OpenVPN; mostly same as CLIENT_AUTHTYPE_CERT, but without
|
||||
// signature verification, because it was already performed during TLS handshake.
|
||||
@@ -2014,25 +2060,14 @@ bool ServerAccept(CONNECTION *c)
|
||||
error_detail = "ERR_AUTHTYPE_NOT_SUPPORTED";
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
if (auth_ret == false)
|
||||
{
|
||||
// Get client IP to feed tools such as Fail2Ban
|
||||
char ip[64];
|
||||
IPToStr(ip, sizeof(ip), &c->FirstSock->RemoteIP);
|
||||
// Authentication failure
|
||||
HLog(hub, "LH_AUTH_NG", c->Name, username, ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Authentication success
|
||||
HLog(hub, "LH_AUTH_OK", c->Name, username);
|
||||
}
|
||||
}
|
||||
|
||||
if (auth_ret == false)
|
||||
{
|
||||
// Authentication failure
|
||||
char ip[64];
|
||||
IPToStr(ip, sizeof(ip), &c->FirstSock->RemoteIP);
|
||||
HLog(hub, "LH_AUTH_NG", c->Name, username, ip);
|
||||
|
||||
Unlock(hub->lock);
|
||||
ReleaseHub(hub);
|
||||
FreePack(p);
|
||||
@@ -2046,13 +2081,12 @@ bool ServerAccept(CONNECTION *c)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_empty_password)
|
||||
if (is_empty_password)
|
||||
{
|
||||
SOCK *s = c->FirstSock;
|
||||
const SOCK *s = c->FirstSock;
|
||||
if (s != NULL && s->RemoteIP.addr[0] != 127)
|
||||
{
|
||||
if(StrCmpi(username, ADMINISTRATOR_USERNAME) == 0 ||
|
||||
GetHubAdminOption(hub, "deny_empty_password") != 0)
|
||||
if (StrCmpi(username, ADMINISTRATOR_USERNAME) == 0 || GetHubAdminOption(hub, "deny_empty_password") != 0)
|
||||
{
|
||||
// When the password is empty, remote connection is not acceptable
|
||||
HLog(hub, "LH_LOCAL_ONLY", c->Name, username);
|
||||
@@ -2066,6 +2100,8 @@ bool ServerAccept(CONNECTION *c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HLog(hub, "LH_AUTH_OK", c->Name, username);
|
||||
}
|
||||
|
||||
policy = NULL;
|
||||
@@ -6592,6 +6628,24 @@ PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_pass
|
||||
return p;
|
||||
}
|
||||
|
||||
// Generate a packet of WireGuard key login
|
||||
PACK *PackLoginWithWireGuardKey(char *key)
|
||||
{
|
||||
PACK *p;
|
||||
// Validate arguments
|
||||
if (key == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = NewPack();
|
||||
PackAddStr(p, "method", "login");
|
||||
PackAddInt(p, "authtype", AUTHTYPE_WIREGUARD_KEY);
|
||||
PackAddStr(p, "key", key);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// Generate a packet of OpenVPN certificate login
|
||||
PACK *PackLoginWithOpenVPNCertificate(char *hubname, char *username, X *x)
|
||||
{
|
||||
|
||||
@@ -134,6 +134,7 @@ PACK *PackLoginWithAnonymous(char *hubname, char *username);
|
||||
PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password);
|
||||
PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_password);
|
||||
PACK *PackLoginWithCert(char *hubname, char *username, X *x, void *sign, UINT sign_size);
|
||||
PACK *PackLoginWithWireGuardKey(char *key);
|
||||
PACK *PackLoginWithOpenVPNCertificate(char *hubname, char *username, X *x);
|
||||
bool GetMethodFromPack(PACK *p, char *method, UINT size);
|
||||
bool GetHubnameAndUsernameFromPack(PACK *p, char *username, UINT username_size,
|
||||
|
||||
+78
-5
@@ -402,6 +402,11 @@ void SiCheckDeadLockMain(SERVER *s, UINT timeout)
|
||||
CheckDeadLock(cedar->CaList->lock, timeout, "cedar->CaList->lock");
|
||||
}
|
||||
|
||||
if (cedar->WgkList != NULL)
|
||||
{
|
||||
CheckDeadLock(cedar->WgkList->lock, timeout, "cedar->WgkList->lock");
|
||||
}
|
||||
|
||||
if (cedar->TrafficLock != NULL)
|
||||
{
|
||||
CheckDeadLock(cedar->TrafficLock, timeout, "cedar->TrafficLock");
|
||||
@@ -2279,6 +2284,8 @@ void SiSetDefaultHubOption(HUB_OPTION *o)
|
||||
return;
|
||||
}
|
||||
|
||||
o->DefaultGateway = SetIP32(192, 168, 30, 1);
|
||||
o->DefaultSubnet = SetIP32(255, 255, 255, 0);
|
||||
o->MaxSession = 0;
|
||||
o->VlanTypeId = MAC_PROTO_TAGVLAN;
|
||||
o->NoIPv6DefaultRouterInRAWhenIPv6 = true;
|
||||
@@ -2675,16 +2682,13 @@ bool SiIsAzureSupported(SERVER *s)
|
||||
// Read the server settings from the CFG
|
||||
bool SiLoadConfigurationCfg(SERVER *s, FOLDER *root)
|
||||
{
|
||||
FOLDER *f1, *f2, *f3, *f4, *f5, *f6, *f7, *f8, *f;
|
||||
FOLDER *f1, *f2, *f3, *f4, *f5, *f6, *f7, *f8, *f9;
|
||||
// Validate arguments
|
||||
if (s == NULL || root == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
f = NULL;
|
||||
|
||||
|
||||
f1 = CfgGetFolder(root, "ServerConfiguration");
|
||||
f2 = CfgGetFolder(root, "VirtualHUB");
|
||||
f3 = CfgGetFolder(root, "ListenerList");
|
||||
@@ -2693,6 +2697,7 @@ bool SiLoadConfigurationCfg(SERVER *s, FOLDER *root)
|
||||
f6 = CfgGetFolder(root, "LicenseManager");
|
||||
f7 = CfgGetFolder(root, "IPsec");
|
||||
f8 = CfgGetFolder(root, "DDnsClient");
|
||||
f9 = CfgGetFolder(root, "WireGuardKeyList");
|
||||
|
||||
if (f1 == NULL)
|
||||
{
|
||||
@@ -2734,6 +2739,30 @@ bool SiLoadConfigurationCfg(SERVER *s, FOLDER *root)
|
||||
|
||||
if (s->ServerType != SERVER_TYPE_FARM_MEMBER)
|
||||
{
|
||||
TOKEN_LIST *t = CfgEnumFolderToTokenList(f9);
|
||||
if (t != NULL)
|
||||
{
|
||||
LockList(s->Cedar->WgkList);
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < t->NumTokens; ++i)
|
||||
{
|
||||
const char *name = t->Token[i];
|
||||
FOLDER *f = CfgGetFolder(f9, name);
|
||||
if (f != NULL)
|
||||
{
|
||||
WGK *wgk = Malloc(sizeof(WGK));
|
||||
StrCpy(wgk->Key, sizeof(wgk->Key), name);
|
||||
CfgGetStr(f, "Hub", wgk->Hub, sizeof(wgk->Hub));
|
||||
CfgGetStr(f, "User", wgk->User, sizeof(wgk->User));
|
||||
Add(s->Cedar->WgkList, wgk);
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockList(s->Cedar->WgkList);
|
||||
FreeToken(t);
|
||||
}
|
||||
|
||||
SiLoadHubs(s, f2);
|
||||
}
|
||||
|
||||
@@ -3100,9 +3129,28 @@ FOLDER *SiWriteConfigurationToCfg(SERVER *s)
|
||||
|
||||
SiWriteServerCfg(CfgCreateFolder(root, "ServerConfiguration"), s);
|
||||
|
||||
|
||||
if (s->UpdatedServerType != SERVER_TYPE_FARM_MEMBER)
|
||||
{
|
||||
FOLDER *f = CfgCreateFolder(root, "WireGuardKeyList");
|
||||
if (f != NULL)
|
||||
{
|
||||
LockList(s->Cedar->WgkList);
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < LIST_NUM(s->Cedar->WgkList); ++i)
|
||||
{
|
||||
WGK *wgk = LIST_DATA(s->Cedar->WgkList, i);
|
||||
FOLDER *ff = CfgCreateFolder(f, wgk->Key);
|
||||
if (ff != NULL)
|
||||
{
|
||||
CfgAddStr(ff, "Hub", wgk->Hub);
|
||||
CfgAddStr(ff, "User", wgk->User);
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockList(s->Cedar->WgkList);
|
||||
}
|
||||
|
||||
SiWriteHubs(CfgCreateFolder(root, "VirtualHUB"), s);
|
||||
}
|
||||
|
||||
@@ -3757,6 +3805,8 @@ void SiLoadHubOptionCfg(FOLDER *f, HUB_OPTION *o)
|
||||
return;
|
||||
}
|
||||
|
||||
o->DefaultGateway = CfgGetIp32(f, "DefaultGateway");
|
||||
o->DefaultSubnet = CfgGetIp32(f, "DefaultSubnet");
|
||||
o->MaxSession = CfgGetInt(f, "MaxSession");
|
||||
o->NoArpPolling = CfgGetBool(f, "NoArpPolling");
|
||||
o->NoIPv6AddrPolling = CfgGetBool(f, "NoIPv6AddrPolling");
|
||||
@@ -3904,6 +3954,8 @@ void SiWriteHubOptionCfg(FOLDER *f, HUB_OPTION *o)
|
||||
return;
|
||||
}
|
||||
|
||||
CfgAddIp32(f, "DefaultGateway", o->DefaultGateway);
|
||||
CfgAddIp32(f, "DefaultSubnet", o->DefaultSubnet);
|
||||
CfgAddInt(f, "MaxSession", o->MaxSession);
|
||||
CfgAddBool(f, "NoArpPolling", o->NoArpPolling);
|
||||
CfgAddBool(f, "NoIPv6AddrPolling", o->NoIPv6AddrPolling);
|
||||
@@ -10295,6 +10347,27 @@ int CompareHubList(void *p1, void *p2)
|
||||
return StrCmpi(h1->Name, h2->Name);
|
||||
}
|
||||
|
||||
// Search in WireGuard key list
|
||||
int CompareWgk(void *p1, void *p2)
|
||||
{
|
||||
WGK *wgk_1, *wgk_2;
|
||||
|
||||
if (p1 == NULL || p2 == NULL)
|
||||
{
|
||||
return (p1 == NULL && p2 == NULL ? 0 : (p1 == NULL ? -1 : 1));
|
||||
}
|
||||
|
||||
wgk_1 = *(WGK **)p1;
|
||||
wgk_2 = *(WGK **)p2;
|
||||
|
||||
if (wgk_1 == NULL || wgk_2 == NULL)
|
||||
{
|
||||
return (wgk_1 == NULL && wgk_2 == NULL ? 0 : (wgk_1 == NULL ? -1 : 1));
|
||||
}
|
||||
|
||||
return StrCmp(wgk_1->Key, wgk_2->Key);
|
||||
}
|
||||
|
||||
// Connection thread to the controller
|
||||
void SiConnectToControllerThread(THREAD *thread, void *param)
|
||||
{
|
||||
|
||||
@@ -150,6 +150,14 @@ struct OPENVPN_SSTP_CONFIG
|
||||
bool EnableSSTP; // SSTP is enabled
|
||||
};
|
||||
|
||||
// WireGuard key structure
|
||||
struct WGK
|
||||
{
|
||||
char Key[WG_KEY_BASE64_SIZE];
|
||||
char Hub[MAX_HUBNAME_LEN + 1];
|
||||
char User[MAX_USERNAME_LEN + 1];
|
||||
};
|
||||
|
||||
// Server object
|
||||
struct SERVER
|
||||
{
|
||||
@@ -631,6 +639,8 @@ void SiUpdateCurrentRegion(CEDAR *c, char *region, bool force_update);
|
||||
void SiGetCurrentRegion(CEDAR *c, char *region, UINT region_size);
|
||||
bool SiIsEnterpriseFunctionsRestrictedOnOpenSource(CEDAR *c);
|
||||
|
||||
int CompareWgk(void *p1, void *p2);
|
||||
|
||||
#endif // SERVER_H
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user