mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2026-04-21 14:29:27 +03:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 019261e47f | |||
| bd1512f15b | |||
| 33d682beee | |||
| 476638b7d9 | |||
| bc2d951000 | |||
| e0c86ab4a6 | |||
| 5130f1a4da | |||
| 13f15384f2 | |||
| bbda0c298d | |||
| e42aa6bf78 | |||
| ef05c4f0c4 | |||
| 7f6e527b47 | |||
| a0afd98744 | |||
| ae448abdad | |||
| cfe854b339 | |||
| c075bd85a8 | |||
| 6f749ab71c | |||
| 0e36e095f0 | |||
| 34e4d4a54b | |||
| df3ea19f0e | |||
| 9da4aabda5 | |||
| 3cb3dd20fc | |||
| b551b77e25 | |||
| 609b8f4a5e | |||
| 0a87ff8fbd | |||
| 6016f84315 | |||
| 9d27b935b7 | |||
| 1e1104d3ba | |||
| 074efb5479 | |||
| fe460de5a6 | |||
| 6ef941db21 | |||
| d7d3ec8cac | |||
| 68e9f0b593 | |||
| f1012da5fb | |||
| 1411d4ceb4 | |||
| a3176175f9 | |||
| 88af7986b4 | |||
| 38f102e2e7 | |||
| c32184495b | |||
| 304364719c | |||
| 4a4c1c79de |
@@ -4,6 +4,7 @@ name: Coverity
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -11,7 +12,7 @@ permissions:
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'SoftEtherVPN' }}
|
||||
if: ${{ github.repository_owner == 'SoftEtherVPN' || github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
||||
@@ -8,10 +8,11 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [
|
||||
{ ARCHITECTURE: x86, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/bin/clang-cl.exe", VCPKG_TRIPLET: "x86-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars32.bat"},
|
||||
{ ARCHITECTURE: x64, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin/clang-cl.exe", VCPKG_TRIPLET: "x64-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"}
|
||||
{ ARCHITECTURE: x86, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/bin/clang-cl.exe", VCPKG_TRIPLET: "x86-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars32.bat", RUNNER: "windows-latest", CMAKE_EXTRA_FLAGS: ""},
|
||||
{ ARCHITECTURE: x64, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin/clang-cl.exe", VCPKG_TRIPLET: "x64-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat", RUNNER: "windows-latest", CMAKE_EXTRA_FLAGS: ""},
|
||||
{ ARCHITECTURE: arm64, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/ARM64/bin/clang-cl.exe", VCPKG_TRIPLET: "arm64-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsarm64.bat", RUNNER: "windows-11-arm", CMAKE_EXTRA_FLAGS: "-DOQS_PERMIT_UNSUPPORTED_ARCHITECTURE=ON"}
|
||||
]
|
||||
runs-on: windows-latest
|
||||
runs-on: ${{ matrix.platform.RUNNER }}
|
||||
name: ${{ matrix.platform.ARCHITECTURE }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -33,12 +34,13 @@ jobs:
|
||||
COMPILER_PATH: ${{ matrix.platform.COMPILER_PATH }}
|
||||
VCPKG_TRIPLET: ${{ matrix.platform.VCPKG_TRIPLET }}
|
||||
VCVARS_PATH: ${{ matrix.platform.VCVARS_PATH }}
|
||||
CMAKE_EXTRA_FLAGS: ${{ matrix.platform.CMAKE_EXTRA_FLAGS }}
|
||||
run: |
|
||||
set BUILD_NUMBER=0
|
||||
mkdir build
|
||||
cd build
|
||||
call "%VCVARS_PATH%"
|
||||
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="C:\vcpkg\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=%VCPKG_TRIPLET% -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER="%COMPILER_PATH%" -DCMAKE_CXX_COMPILER="%COMPILER_PATH%" -DBUILD_NUMBER=%BUILD_NUMBER% ..
|
||||
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="C:\vcpkg\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=%VCPKG_TRIPLET% -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER="%COMPILER_PATH%" -DCMAKE_CXX_COMPILER="%COMPILER_PATH%" -DBUILD_NUMBER=%BUILD_NUMBER% %CMAKE_EXTRA_FLAGS% ..
|
||||
cmake --build .
|
||||
mkdir installers
|
||||
vpnsetup /SFXMODE:vpnclient /SFXOUT:"installers\softether-vpnclient-%VERSION%.%BUILD_NUMBER%.%ARCHITECTURE%.exe"
|
||||
|
||||
@@ -26,13 +26,14 @@ jobs:
|
||||
uses: softprops/action-gh-release@v1
|
||||
build-windows:
|
||||
name: ${{ matrix.platform.ARCHITECTURE }}
|
||||
runs-on: windows-latest
|
||||
runs-on: ${{ matrix.platform.RUNNER }}
|
||||
needs: ["release"]
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [
|
||||
{ ARCHITECTURE: x86, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/bin/clang-cl.exe", VCPKG_TRIPLET: "x86-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars32.bat"},
|
||||
{ ARCHITECTURE: x64, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin/clang-cl.exe", VCPKG_TRIPLET: "x64-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"}
|
||||
{ ARCHITECTURE: x86, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/bin/clang-cl.exe", VCPKG_TRIPLET: "x86-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars32.bat", RUNNER: "windows-latest", CMAKE_EXTRA_FLAGS: ""},
|
||||
{ ARCHITECTURE: x64, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin/clang-cl.exe", VCPKG_TRIPLET: "x64-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat", RUNNER: "windows-latest", CMAKE_EXTRA_FLAGS: ""},
|
||||
{ ARCHITECTURE: arm64, COMPILER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/ARM64/bin/clang-cl.exe", VCPKG_TRIPLET: "arm64-windows-static", VCVARS_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsarm64.bat", RUNNER: "windows-11-arm", CMAKE_EXTRA_FLAGS: "-DOQS_PERMIT_UNSUPPORTED_ARCHITECTURE=ON"}
|
||||
]
|
||||
steps:
|
||||
- name: "Checkout repository"
|
||||
@@ -57,11 +58,12 @@ jobs:
|
||||
COMPILER_PATH: ${{ matrix.platform.COMPILER_PATH }}
|
||||
VCPKG_TRIPLET: ${{ matrix.platform.VCPKG_TRIPLET }}
|
||||
VCVARS_PATH: ${{ matrix.platform.VCVARS_PATH }}
|
||||
CMAKE_EXTRA_FLAGS: ${{ matrix.platform.CMAKE_EXTRA_FLAGS }}
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
call "%VCVARS_PATH%"
|
||||
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="C:\vcpkg\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=%VCPKG_TRIPLET% -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER="%COMPILER_PATH%" -DCMAKE_CXX_COMPILER="%COMPILER_PATH%" -DBUILD_NUMBER=%BUILD_NUMBER% ..
|
||||
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="C:\vcpkg\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=%VCPKG_TRIPLET% -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER="%COMPILER_PATH%" -DCMAKE_CXX_COMPILER="%COMPILER_PATH%" -DBUILD_NUMBER=%BUILD_NUMBER% %CMAKE_EXTRA_FLAGS% ..
|
||||
cmake --build .
|
||||
mkdir installers
|
||||
vpnsetup /SFXMODE:vpnclient /SFXOUT:"installers\softether-vpnclient-%VERSION%.%BUILD_NUMBER%.%ARCHITECTURE%.exe"
|
||||
|
||||
@@ -210,3 +210,9 @@ developer_tools/stbchecker/**/*.binlog
|
||||
developer_tools/stbchecker/**/*.nvuser
|
||||
developer_tools/stbchecker/**/.mfractor/
|
||||
/vcpkg_installed
|
||||
|
||||
# Build directories
|
||||
/_codeql_build_dir/
|
||||
/_codeql_detected_source_root
|
||||
/build/
|
||||
/build_test/
|
||||
|
||||
@@ -88,6 +88,10 @@ into it. So that is what will be described below.
|
||||
|
||||
Cross compile x86 executables with 64-bit compiler
|
||||
|
||||
- arm64-on-x64
|
||||
|
||||
Cross compile arm64 executables with x64t compiler
|
||||
|
||||
On 64-bit Windows, all four configurations can be used. 32-bit platforms can only use 32-bit compiler.
|
||||
|
||||
1. Visual Studio will try generating CMake cache. If not, click **Project -> Configure Cache** or **Generate Cache**.
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# How to build and install SoftEther VPN on Windows ARM64
|
||||
|
||||
This document describes how to build SoftEther VPN for Windows ARM64 and how to install the VPN Client and Neo6 virtual network adapter on Windows on ARM devices.
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
- Build host: Windows x64
|
||||
|
||||
- Target device: Windows 10 / Windows 11 ARM64
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
**Notes before building**: ARM64 builds are cross-compiled from an x64 Windows host. An existing x64-native build is required to generate hamcore.se2.
|
||||
1. Follow [BUILD_WINDOWS.md](BUILD_WINDOWS.md##Building)
|
||||
|
||||
1. Build x64 (Native): From the build menu, select x64-on-x64. Complete the build successfully. This build is required to generate shared resources
|
||||
|
||||
1. Build ARM64 (Cross-Compiled): From the same build menu, select arm64-on-x64.
|
||||
Build the ARM64 version of SoftEther VPN.
|
||||
|
||||
1. Building the Neo6 Virtual Network Adapter (ARM64)
|
||||
|
||||
Open the following project in Visual Studio:
|
||||
```
|
||||
.\src\Neo6\Neo6.vcxproj
|
||||
```
|
||||
|
||||
SoftEther VPN Client uses the Neo6 virtual network adapter.
|
||||
|
||||
|
||||
Driver Output Files
|
||||
The ARM64 driver package includes:
|
||||
```
|
||||
Neo6_arm64_VPN.sys
|
||||
Neo6_arm64_VPN.inf
|
||||
```
|
||||
Driver Signing and Installation (Windows ARM64)
|
||||
```
|
||||
Enable test-signing mode: bcdedit /set testsigning on
|
||||
Reboot the system.
|
||||
Testing signing:
|
||||
Install the Neo6 ARM64 driver.
|
||||
```
|
||||
# Summary
|
||||
|
||||
SoftEther VPN can be cross-compiled for Windows ARM64 on an x64 host
|
||||
VPN Client works natively on Windows on ARM
|
||||
Neo6 ARM64 driver requires Microsoft signing for production use
|
||||
Test-signing is suitable for local development only
|
||||
+5
-3
@@ -8739,7 +8739,7 @@ UINT StSetHubRadius(ADMIN *a, RPC_RADIUS *t)
|
||||
}
|
||||
|
||||
//SetRadiusServer(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret);
|
||||
SetRadiusServerEx(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret, t->RadiusRetryInterval);
|
||||
SetRadiusServerEx2(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret, t->RadiusRetryInterval, t->RadiusRetryTimeout);
|
||||
|
||||
ALog(a, h, "LA_SET_HUB_RADIUS");
|
||||
|
||||
@@ -8778,8 +8778,8 @@ UINT StGetHubRadius(ADMIN *a, RPC_RADIUS *t)
|
||||
Zero(t, sizeof(RPC_RADIUS));
|
||||
//GetRadiusServer(h, t->RadiusServerName, sizeof(t->RadiusServerName),
|
||||
// &t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret));
|
||||
GetRadiusServerEx(h, t->RadiusServerName, sizeof(t->RadiusServerName),
|
||||
&t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret), &t->RadiusRetryInterval);
|
||||
GetRadiusServerEx2(h, t->RadiusServerName, sizeof(t->RadiusServerName),
|
||||
&t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret), &t->RadiusRetryInterval, &t->RadiusRetryTimeout);
|
||||
|
||||
ReleaseHub(h);
|
||||
|
||||
@@ -13031,6 +13031,7 @@ void InRpcRadius(RPC_RADIUS *t, PACK *p)
|
||||
PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
|
||||
PackGetStr(p, "RadiusSecret", t->RadiusSecret, sizeof(t->RadiusSecret));
|
||||
t->RadiusRetryInterval = PackGetInt(p, "RadiusRetryInterval");
|
||||
t->RadiusRetryTimeout = PackGetInt(p, "RadiusRetryTimeout");
|
||||
}
|
||||
void OutRpcRadius(PACK *p, RPC_RADIUS *t)
|
||||
{
|
||||
@@ -13045,6 +13046,7 @@ void OutRpcRadius(PACK *p, RPC_RADIUS *t)
|
||||
PackAddStr(p, "HubName", t->HubName);
|
||||
PackAddStr(p, "RadiusSecret", t->RadiusSecret);
|
||||
PackAddInt(p, "RadiusRetryInterval", t->RadiusRetryInterval);
|
||||
PackAddInt(p, "RadiusRetryTimeout", t->RadiusRetryTimeout);
|
||||
}
|
||||
|
||||
// RPC_HUB
|
||||
|
||||
@@ -259,6 +259,7 @@ struct RPC_RADIUS
|
||||
UINT RadiusPort; // Radius port number
|
||||
char RadiusSecret[MAX_PASSWORD_LEN + 1]; // Secret key
|
||||
UINT RadiusRetryInterval; // Radius retry interval
|
||||
UINT RadiusRetryTimeout; // Radius retry timeout
|
||||
};
|
||||
|
||||
// Specify the HUB
|
||||
|
||||
@@ -11791,6 +11791,9 @@ UINT PsRadiusServerSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
{"[server_name:port]", CmdPrompt, _UU("CMD_RadiusServerSet_Prompt_Host"), CmdEvalNotEmpty, NULL},
|
||||
{"SECRET", CmdPromptChoosePassword, _UU("CMD_RadiusServerSet_Prompt_Secret"), NULL, NULL},
|
||||
{"RETRY_INTERVAL", CmdPrompt, _UU("CMD_RadiusServerSet_Prompt_RetryInterval"), CmdEvalMinMax, &minmax},
|
||||
|
||||
// Support for setting timeout through commandline not added
|
||||
// {"RETRY_TIMEOUT", CmdPrompt, _UU("CMD_RadiusServerSet_Prompt_RetryTimeout"), CmdEvalMinMax, &minmax},
|
||||
};
|
||||
|
||||
// If virtual HUB is not selected, it's an error
|
||||
@@ -11815,6 +11818,7 @@ UINT PsRadiusServerSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
StrCpy(t.RadiusServerName, sizeof(t.RadiusServerName), host);
|
||||
StrCpy(t.RadiusSecret, sizeof(t.RadiusSecret), GetParamStr(o, "SECRET"));
|
||||
t.RadiusRetryInterval = GetParamInt(o, "RETRY_INTERVAL");
|
||||
// t.RadiusRetryTimeout = GetParamInt(o, "RETRY_TIMEOUT");
|
||||
|
||||
Free(host);
|
||||
|
||||
@@ -11938,6 +11942,9 @@ UINT PsRadiusServerGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
||||
|
||||
UniToStri(tmp, t.RadiusRetryInterval);
|
||||
CtInsert(ct, _UU("CMD_RadiusServerGet_RetryInterval"), tmp);
|
||||
|
||||
UniToStri(tmp, t.RadiusRetryTimeout);
|
||||
CtInsert(ct, _UU("CMD_RadiusServerGet_RetryTimeout"), tmp);
|
||||
}
|
||||
|
||||
CtFree(ct, c);
|
||||
|
||||
+31
-10
@@ -99,6 +99,7 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch
|
||||
char radius_servers[MAX_PATH] = {0};
|
||||
UINT radius_port = 0;
|
||||
UINT radius_retry_interval = 0;
|
||||
UINT radius_retry_timeout = 0;
|
||||
char radius_secret[MAX_PATH] = {0};
|
||||
char radius_suffix_filter[MAX_PATH] = {0};
|
||||
if (cedar == NULL || hubname == NULL || client_ip_str == NULL || username == NULL)
|
||||
@@ -115,8 +116,8 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch
|
||||
|
||||
if (hub != NULL)
|
||||
{
|
||||
if (GetRadiusServerEx2(hub, radius_servers, sizeof(radius_servers), &radius_port, radius_secret,
|
||||
sizeof(radius_secret), &radius_retry_interval, radius_suffix_filter, sizeof(radius_suffix_filter)))
|
||||
if (GetRadiusServerEx3(hub, radius_servers, sizeof(radius_servers), &radius_port, radius_secret,
|
||||
sizeof(radius_secret), &radius_retry_interval, &radius_retry_timeout, radius_suffix_filter, sizeof(radius_suffix_filter)))
|
||||
{
|
||||
bool use_peap = hub->RadiusUsePeapInsteadOfEap;
|
||||
|
||||
@@ -6415,17 +6416,23 @@ void ReleaseHub(HUB *h)
|
||||
bool GetRadiusServer(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size)
|
||||
{
|
||||
UINT interval;
|
||||
|
||||
return GetRadiusServerEx(hub, name, size, port, secret, secret_size, &interval);
|
||||
}
|
||||
bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval)
|
||||
{
|
||||
return GetRadiusServerEx2(hub, name, size, port, secret, secret_size, interval, NULL, 0);
|
||||
bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval) {
|
||||
UINT timeout;
|
||||
|
||||
return GetRadiusServerEx2(hub, name, size, port, secret, secret_size, interval, &timeout);
|
||||
}
|
||||
bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, char *suffix_filter, UINT suffix_filter_size)
|
||||
bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout)
|
||||
{
|
||||
return GetRadiusServerEx3(hub, name, size, port, secret, secret_size, interval, timeout, NULL, 0);
|
||||
}
|
||||
bool GetRadiusServerEx3(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout, char *suffix_filter, UINT suffix_filter_size)
|
||||
{
|
||||
bool ret = false;
|
||||
// Validate arguments
|
||||
if (hub == NULL || name == NULL || port == NULL || secret == NULL || interval == NULL)
|
||||
if (hub == NULL || name == NULL || port == NULL || secret == NULL || interval == NULL || timeout == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -6439,6 +6446,7 @@ bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secre
|
||||
StrCpy(name, size, hub->RadiusServerName);
|
||||
*port = hub->RadiusServerPort;
|
||||
*interval = hub->RadiusRetryInterval;
|
||||
*timeout = hub->RadiusRetryTimeout;
|
||||
|
||||
tmp_size = hub->RadiusSecret->Size + 1;
|
||||
tmp = ZeroMalloc(tmp_size);
|
||||
@@ -6465,6 +6473,10 @@ void SetRadiusServer(HUB *hub, char *name, UINT port, char *secret)
|
||||
SetRadiusServerEx(hub, name, port, secret, RADIUS_RETRY_INTERVAL);
|
||||
}
|
||||
void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval)
|
||||
{
|
||||
SetRadiusServerEx2(hub, name, port, secret, interval, RADIUS_RETRY_TIMEOUT);
|
||||
}
|
||||
void SetRadiusServerEx2(HUB *hub, char *name, UINT port, char *secret, UINT interval, UINT timeout)
|
||||
{
|
||||
// Validate arguments
|
||||
if (hub == NULL)
|
||||
@@ -6484,19 +6496,28 @@ void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT inter
|
||||
hub->RadiusServerName = NULL;
|
||||
hub->RadiusServerPort = 0;
|
||||
hub->RadiusRetryInterval = RADIUS_RETRY_INTERVAL;
|
||||
hub->RadiusRetryTimeout = RADIUS_RETRY_TIMEOUT;
|
||||
|
||||
FreeBuf(hub->RadiusSecret);
|
||||
}
|
||||
else
|
||||
{
|
||||
hub->RadiusServerName = CopyStr(name);
|
||||
hub->RadiusServerPort = port;
|
||||
|
||||
if (timeout == 0) {
|
||||
timeout = RADIUS_RETRY_TIMEOUT;
|
||||
}
|
||||
hub->RadiusRetryTimeout = timeout;
|
||||
|
||||
if (interval == 0)
|
||||
{
|
||||
hub->RadiusRetryInterval = RADIUS_RETRY_INTERVAL;
|
||||
hub->RadiusRetryInterval = RADIUS_RETRY_INTERVAL; ///What happens here is that RADIUS_RETRY_TIMEOUT is not configurable, and RADIUS_RETRY_INTERVAL is set to the timeout if it's larger.
|
||||
}
|
||||
else if (interval > RADIUS_RETRY_TIMEOUT)
|
||||
|
||||
if (interval > timeout)
|
||||
{
|
||||
hub->RadiusRetryInterval = RADIUS_RETRY_TIMEOUT;
|
||||
hub->RadiusRetryInterval = timeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+4
-1
@@ -341,6 +341,7 @@ struct HUB
|
||||
char *RadiusServerName; // Radius server name
|
||||
UINT RadiusServerPort; // Radius server port number
|
||||
UINT RadiusRetryInterval; // Radius retry interval
|
||||
UINT RadiusRetryTimeout; // Radius timeout, it will no longer retry
|
||||
BUF *RadiusSecret; // Radius shared key
|
||||
char RadiusSuffixFilter[MAX_SIZE]; // Radius suffix filter
|
||||
char RadiusRealm[MAX_SIZE]; // Radius realm (optional)
|
||||
@@ -482,9 +483,11 @@ void GetAccessListStr(char *str, UINT size, ACCESS *a);
|
||||
void DeleteOldIpTableEntry(LIST *o);
|
||||
void SetRadiusServer(HUB *hub, char *name, UINT port, char *secret);
|
||||
void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval);
|
||||
void SetRadiusServerEx2(HUB *hub, char *name, UINT port, char *secret, UINT interval, UINT timeout);
|
||||
bool GetRadiusServer(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size);
|
||||
bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval);
|
||||
bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, char *suffix_filter, UINT suffix_filter_size);
|
||||
bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout);
|
||||
bool GetRadiusServerEx3(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout, char *suffix_filter, UINT suffix_filter_size);
|
||||
int CompareCert(void *p1, void *p2);
|
||||
void GetHubLogSetting(HUB *h, HUB_LOG *setting);
|
||||
void SetHubLogSetting(HUB *h, HUB_LOG *setting);
|
||||
|
||||
+37
-3
@@ -11,6 +11,7 @@
|
||||
#include "Connection.h"
|
||||
#include "Logging.h"
|
||||
#include "Proto_EtherIP.h"
|
||||
#include "Proto_IKEv2.h"
|
||||
#include "Proto_IPsec.h"
|
||||
#include "Proto_L2TP.h"
|
||||
#include "Server.h"
|
||||
@@ -35,7 +36,25 @@ void ProcIKEPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
|
||||
|
||||
if (p->Type == IKE_UDP_TYPE_ISAKMP)
|
||||
{
|
||||
// ISAKMP (IKE) packet
|
||||
IKE_HEADER *raw_hdr;
|
||||
|
||||
// Check packet is large enough for the IKE header
|
||||
if (p->Size < sizeof(IKE_HEADER))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
raw_hdr = (IKE_HEADER *)p->Data;
|
||||
|
||||
// Dispatch IKEv2 packets by version field
|
||||
if (raw_hdr->Version == IKEv2_VERSION)
|
||||
{
|
||||
ProcIKEv2PacketRecv(ike, p);
|
||||
return;
|
||||
}
|
||||
|
||||
// IKEv1 / ISAKMP packet
|
||||
{
|
||||
IKE_PACKET *header;
|
||||
|
||||
header = ParseIKEPacketHeader(p);
|
||||
@@ -44,8 +63,6 @@ void ProcIKEPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug("InitiatorCookie: %I64u, ResponderCookie: %I64u\n", header->InitiatorCookie, header->ResponderCookie);
|
||||
|
||||
switch (header->ExchangeType)
|
||||
{
|
||||
case IKE_EXCHANGE_TYPE_MAIN: // Main mode
|
||||
@@ -70,6 +87,7 @@ void ProcIKEPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
|
||||
|
||||
IkeFree(header);
|
||||
}
|
||||
}
|
||||
else if (p->Type == IKE_UDP_TYPE_ESP)
|
||||
{
|
||||
// ESP packet
|
||||
@@ -5645,6 +5663,9 @@ void ProcessIKEInterrupts(IKE_SERVER *ike)
|
||||
}
|
||||
while (ike->StateHasChanged);
|
||||
|
||||
// IKEv2 interrupt processing
|
||||
ProcessIKEv2Interrupts(ike);
|
||||
|
||||
// Maintenance of the thread list
|
||||
MaintainThreadList(ike->ThreadList);
|
||||
/*Debug("ike->ThreadList: %u\n", LIST_NUM(ike->ThreadList));
|
||||
@@ -5823,6 +5844,17 @@ void FreeIKEServer(IKE_SERVER *ike)
|
||||
|
||||
ReleaseList(ike->ClientList);
|
||||
|
||||
// Free IKEv2 SAs
|
||||
{
|
||||
UINT j;
|
||||
for (j = 0; j < LIST_NUM(ike->IKEv2SaList); j++)
|
||||
{
|
||||
IKEv2_SA *sa2 = LIST_DATA(ike->IKEv2SaList, j);
|
||||
IKEv2FreeSA(ike, sa2);
|
||||
}
|
||||
}
|
||||
ReleaseList(ike->IKEv2SaList);
|
||||
|
||||
ReleaseSockEvent(ike->SockEvent);
|
||||
|
||||
IPsecLog(ike, NULL, NULL, NULL, "LI_STOP");
|
||||
@@ -5869,6 +5901,8 @@ IKE_SERVER *NewIKEServer(CEDAR *cedar, IPSEC_SERVER *ipsec)
|
||||
|
||||
ike->ThreadList = NewThreadList();
|
||||
|
||||
ike->IKEv2SaList = NewList(CmpIKEv2SA);
|
||||
|
||||
IPsecLog(ike, NULL, NULL, NULL, "LI_START");
|
||||
|
||||
return ike;
|
||||
|
||||
@@ -268,6 +268,10 @@ struct IKE_SERVER
|
||||
|
||||
// Setting data
|
||||
char Secret[MAX_SIZE]; // Pre-shared key
|
||||
|
||||
// IKEv2 state
|
||||
LIST *IKEv2SaList; // IKEv2 SA list
|
||||
UINT CurrentIKEv2SaId; // IKEv2 SA ID counter
|
||||
};
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,292 @@
|
||||
// SoftEther VPN Source Code - Developer Edition Master Branch
|
||||
// Cedar Communication Module
|
||||
|
||||
|
||||
// Proto_IKEv2.h
|
||||
// Header for IKEv2 (RFC 7296) implementation
|
||||
|
||||
#ifndef PROTO_IKEV2_H
|
||||
#define PROTO_IKEV2_H
|
||||
|
||||
#include "Proto_IKE.h"
|
||||
#include "Proto_IkePacket.h"
|
||||
|
||||
//// IKEv2 Header Flags (RFC 7296 Section 3.1)
|
||||
#define IKEv2_FLAG_RESPONSE 0x20
|
||||
#define IKEv2_FLAG_VERSION 0x10
|
||||
#define IKEv2_FLAG_INITIATOR 0x08
|
||||
|
||||
//// IKEv2 Payload Types (RFC 7296 Section 3.3)
|
||||
#define IKEv2_PAYLOAD_NONE 0
|
||||
#define IKEv2_PAYLOAD_SA 33
|
||||
#define IKEv2_PAYLOAD_KE 34
|
||||
#define IKEv2_PAYLOAD_IDi 35
|
||||
#define IKEv2_PAYLOAD_IDr 36
|
||||
#define IKEv2_PAYLOAD_CERT 37
|
||||
#define IKEv2_PAYLOAD_CERTREQ 38
|
||||
#define IKEv2_PAYLOAD_AUTH 39
|
||||
#define IKEv2_PAYLOAD_NONCE 40
|
||||
#define IKEv2_PAYLOAD_NOTIFY 41
|
||||
#define IKEv2_PAYLOAD_DELETE 42
|
||||
#define IKEv2_PAYLOAD_VENDOR 43
|
||||
#define IKEv2_PAYLOAD_TSi 44
|
||||
#define IKEv2_PAYLOAD_TSr 45
|
||||
#define IKEv2_PAYLOAD_SK 46
|
||||
#define IKEv2_PAYLOAD_CP 47
|
||||
#define IKEv2_PAYLOAD_EAP 48
|
||||
|
||||
//// IKEv2 Transform Types
|
||||
#define IKEv2_TF_ENCR 1
|
||||
#define IKEv2_TF_PRF 2
|
||||
#define IKEv2_TF_INTEG 3
|
||||
#define IKEv2_TF_DH 4
|
||||
#define IKEv2_TF_ESN 5
|
||||
|
||||
//// IKEv2 Encryption Algorithm IDs
|
||||
#define IKEv2_ENCR_3DES 3
|
||||
#define IKEv2_ENCR_AES_CBC 12
|
||||
|
||||
//// IKEv2 PRF Algorithm IDs
|
||||
#define IKEv2_PRF_HMAC_MD5 1
|
||||
#define IKEv2_PRF_HMAC_SHA1 2
|
||||
#define IKEv2_PRF_HMAC_SHA2_256 5
|
||||
#define IKEv2_PRF_HMAC_SHA2_384 6
|
||||
#define IKEv2_PRF_HMAC_SHA2_512 7
|
||||
|
||||
//// IKEv2 Integrity Algorithm IDs
|
||||
#define IKEv2_INTEG_HMAC_MD5_96 1 // key=16, icv=12
|
||||
#define IKEv2_INTEG_HMAC_SHA1_96 2 // key=20, icv=12
|
||||
#define IKEv2_INTEG_HMAC_SHA2_256_128 12 // key=32, icv=16
|
||||
#define IKEv2_INTEG_HMAC_SHA2_384_192 13 // key=48, icv=24
|
||||
#define IKEv2_INTEG_HMAC_SHA2_512_256 14 // key=64, icv=32
|
||||
|
||||
//// IKEv2 DH Groups (same wire values as IKEv1)
|
||||
#define IKEv2_DH_1024_MODP 2
|
||||
#define IKEv2_DH_1536_MODP 5
|
||||
#define IKEv2_DH_2048_MODP 14
|
||||
#define IKEv2_DH_3072_MODP 15
|
||||
#define IKEv2_DH_4096_MODP 16
|
||||
|
||||
//// IKEv2 ESN Values
|
||||
#define IKEv2_ESN_NO_ESN 0
|
||||
#define IKEv2_ESN_YES 1
|
||||
|
||||
//// IKEv2 Notify Message Types (error types < 16384)
|
||||
#define IKEv2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD 1
|
||||
#define IKEv2_NOTIFY_INVALID_IKE_SPI 4
|
||||
#define IKEv2_NOTIFY_INVALID_MAJOR_VERSION 5
|
||||
#define IKEv2_NOTIFY_INVALID_SYNTAX 7
|
||||
#define IKEv2_NOTIFY_INVALID_MESSAGE_ID 9
|
||||
#define IKEv2_NOTIFY_INVALID_SPI 11
|
||||
#define IKEv2_NOTIFY_NO_PROPOSAL_CHOSEN 14
|
||||
#define IKEv2_NOTIFY_INVALID_KE_PAYLOAD 17
|
||||
#define IKEv2_NOTIFY_AUTHENTICATION_FAILED 24
|
||||
#define IKEv2_NOTIFY_TS_UNACCEPTABLE 38
|
||||
|
||||
//// IKEv2 Notify status types (>= 16384)
|
||||
#define IKEv2_NOTIFY_NAT_DETECTION_SOURCE_IP 16388
|
||||
#define IKEv2_NOTIFY_NAT_DETECTION_DESTINATION_IP 16389
|
||||
#define IKEv2_NOTIFY_USE_TRANSPORT_MODE 16391
|
||||
#define IKEv2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED 16394
|
||||
|
||||
//// IKEv2 ID Types
|
||||
#define IKEv2_ID_IPV4_ADDR 1
|
||||
#define IKEv2_ID_FQDN 2
|
||||
#define IKEv2_ID_RFC822_ADDR 3
|
||||
#define IKEv2_ID_IPV6_ADDR 5
|
||||
#define IKEv2_ID_KEY_ID 11
|
||||
|
||||
//// IKEv2 Authentication Methods
|
||||
#define IKEv2_AUTH_RSA_SIGN 1
|
||||
#define IKEv2_AUTH_PSK 2
|
||||
|
||||
//// IKEv2 Traffic Selector Types
|
||||
#define IKEv2_TS_IPV4_ADDR_RANGE 7
|
||||
#define IKEv2_TS_IPV6_ADDR_RANGE 8
|
||||
|
||||
//// IKEv2 Protocol IDs
|
||||
#define IKEv2_PROTO_IKE 1
|
||||
#define IKEv2_PROTO_AH 2
|
||||
#define IKEv2_PROTO_ESP 3
|
||||
|
||||
//// SA states
|
||||
#define IKEv2_SA_STATE_HALF_OPEN 0
|
||||
#define IKEv2_SA_STATE_ESTABLISHED 1
|
||||
|
||||
//// Sizes and limits
|
||||
#define IKEv2_MAX_KEYMAT_SIZE 128
|
||||
#define IKEv2_NONCE_SIZE 32
|
||||
#define IKEv2_NONCE_MIN_SIZE 16
|
||||
#define IKEv2_NONCE_MAX_SIZE 256
|
||||
#define IKEv2_PSK_PAD "Key Pad for IKEv2"
|
||||
#define IKEv2_PSK_PAD_LEN 17
|
||||
|
||||
//// Timeouts
|
||||
#define IKEv2_SA_TIMEOUT_HALF_OPEN 30000
|
||||
#define IKEv2_SA_TIMEOUT_ESTABLISHED (86400ULL * 1000)
|
||||
#define IKEv2_SA_RESEND_INTERVAL 2000
|
||||
#define IKEv2_CHILD_SA_LIFETIME_SECS 3600
|
||||
|
||||
|
||||
//// Structures
|
||||
|
||||
// Negotiated IKE SA transform parameters
|
||||
struct IKEv2_IKETF
|
||||
{
|
||||
UINT EncrAlg; // Encryption algorithm
|
||||
UINT EncrKeyLen; // Encryption key length (bytes)
|
||||
UINT PrfAlg; // PRF algorithm
|
||||
UINT IntegAlg; // Integrity algorithm
|
||||
UINT DhGroup; // DH group number
|
||||
UINT BlockSize; // Cipher block size (bytes)
|
||||
UINT PrfKeyLen; // PRF key length (bytes)
|
||||
UINT PrfOutLen; // PRF output length (bytes)
|
||||
UINT IntegKeyLen; // Integrity key length (bytes)
|
||||
UINT IntegIcvLen; // Integrity ICV length (bytes)
|
||||
};
|
||||
typedef struct IKEv2_IKETF IKEv2_IKETF;
|
||||
|
||||
// Negotiated Child SA transform parameters
|
||||
struct IKEv2_CHILDTF
|
||||
{
|
||||
UINT EncrAlg; // Encryption algorithm
|
||||
UINT EncrKeyLen; // Encryption key length (bytes)
|
||||
UINT IntegAlg; // Integrity algorithm
|
||||
UINT IntegKeyLen; // Integrity key length (bytes)
|
||||
UINT IntegIcvLen; // Integrity ICV length (bytes)
|
||||
UINT DhGroup; // DH group (0 if none)
|
||||
bool UseTransport; // True = transport mode
|
||||
UINT BlockSize; // Cipher block size
|
||||
};
|
||||
typedef struct IKEv2_CHILDTF IKEv2_CHILDTF;
|
||||
|
||||
// IKEv2 SA (one per IKEv2 connection attempt)
|
||||
struct IKEv2_SA
|
||||
{
|
||||
UINT Id;
|
||||
UINT64 InitiatorSPI;
|
||||
UINT64 ResponderSPI;
|
||||
|
||||
IP ClientIP;
|
||||
UINT ClientPort;
|
||||
IP ServerIP;
|
||||
UINT ServerPort;
|
||||
bool IsNatT;
|
||||
|
||||
UINT State;
|
||||
bool Deleting;
|
||||
UINT64 FirstCommTick;
|
||||
UINT64 LastCommTick;
|
||||
|
||||
IKEv2_IKETF Transform;
|
||||
|
||||
// Nonces
|
||||
BUF *Ni;
|
||||
BUF *Nr;
|
||||
|
||||
// DH
|
||||
DH_CTX *Dh;
|
||||
BUF *GxI; // initiator KE value
|
||||
BUF *GxR; // responder KE value (our public key)
|
||||
|
||||
// Derived IKE SA keys (max 64 bytes each)
|
||||
UCHAR SK_d [IKEv2_MAX_KEYMAT_SIZE];
|
||||
UCHAR SK_ai[IKEv2_MAX_KEYMAT_SIZE];
|
||||
UCHAR SK_ar[IKEv2_MAX_KEYMAT_SIZE];
|
||||
UCHAR SK_ei[IKEv2_MAX_KEYMAT_SIZE];
|
||||
UCHAR SK_er[IKEv2_MAX_KEYMAT_SIZE];
|
||||
UCHAR SK_pi[IKEv2_MAX_KEYMAT_SIZE];
|
||||
UCHAR SK_pr[IKEv2_MAX_KEYMAT_SIZE];
|
||||
|
||||
// Crypto key objects for SK payload
|
||||
IKE_CRYPTO_KEY *EncKeyI; // key for SK_ei (decrypt received)
|
||||
IKE_CRYPTO_KEY *EncKeyR; // key for SK_er (encrypt sent)
|
||||
|
||||
// Original IKE_SA_INIT messages for AUTH
|
||||
BUF *InitMsg; // IKE_SA_INIT request (from initiator)
|
||||
BUF *RespMsg; // IKE_SA_INIT response (from us)
|
||||
|
||||
// Initiator identity from IKE_AUTH
|
||||
UCHAR IDi_Type;
|
||||
BUF *IDi_Data;
|
||||
|
||||
// Responder identity (from initiator's optional IDr payload, echoed back)
|
||||
UCHAR IDr_Type;
|
||||
BUF *IDr_Data;
|
||||
|
||||
// Message ID tracking
|
||||
UINT NextExpectedMsgId;
|
||||
|
||||
// Retransmission: cache last response
|
||||
BUF *LastResponse;
|
||||
UINT LastRespMsgId;
|
||||
UINT64 LastRespTick;
|
||||
UINT NumResends;
|
||||
|
||||
// Pointer to IKEv1 IKE_CLIENT created after AUTH
|
||||
IKE_CLIENT *IkeClient;
|
||||
};
|
||||
typedef struct IKEv2_SA IKEv2_SA;
|
||||
|
||||
|
||||
//// Function prototypes
|
||||
|
||||
void ProcIKEv2PacketRecv(IKE_SERVER *ike, UDPPACKET *p);
|
||||
void ProcessIKEv2Interrupts(IKE_SERVER *ike);
|
||||
|
||||
IKEv2_SA *IKEv2NewSA(IKE_SERVER *ike);
|
||||
void IKEv2FreeSA(IKE_SERVER *ike, IKEv2_SA *sa);
|
||||
void IKEv2MarkDeleting(IKE_SERVER *ike, IKEv2_SA *sa);
|
||||
void IKEv2PurgeDeleting(IKE_SERVER *ike);
|
||||
IKEv2_SA *IKEv2FindByInitSPI(IKE_SERVER *ike, UINT64 init_spi, IP *client_ip, UINT client_port);
|
||||
IKEv2_SA *IKEv2FindBySPIPair(IKE_SERVER *ike, UINT64 init_spi, UINT64 resp_spi);
|
||||
int CmpIKEv2SA(void *p1, void *p2);
|
||||
|
||||
void IKEv2ProcSAInit(IKE_SERVER *ike, UDPPACKET *p, IKE_HEADER *hdr);
|
||||
void IKEv2ProcAuth(IKE_SERVER *ike, UDPPACKET *p, IKE_HEADER *hdr, IKEv2_SA *sa,
|
||||
void *payload_data, UINT payload_size, UCHAR first_payload);
|
||||
void IKEv2ProcInformational(IKE_SERVER *ike, UDPPACKET *p, IKE_HEADER *hdr, IKEv2_SA *sa,
|
||||
void *payload_data, UINT payload_size);
|
||||
|
||||
bool IKEv2DeriveKeys(IKE_SERVER *ike, IKEv2_SA *sa);
|
||||
void IKEv2PRF(UINT prf_alg, void *key, UINT key_len,
|
||||
void *data, UINT data_len, void *out);
|
||||
void IKEv2PRFPlus(UINT prf_alg, void *key, UINT key_len,
|
||||
void *seed, UINT seed_len, void *out, UINT out_len);
|
||||
|
||||
bool IKEv2VerifyAuth(IKE_SERVER *ike, IKEv2_SA *sa,
|
||||
UCHAR auth_method, void *auth_data, UINT auth_len);
|
||||
void IKEv2ComputeOurAuth(IKE_SERVER *ike, IKEv2_SA *sa, void *out, UINT *out_len);
|
||||
|
||||
bool IKEv2CreateChildSAForClient(IKE_SERVER *ike, IKEv2_SA *sa,
|
||||
IKEv2_CHILDTF *ctf, UINT spi_i, UINT spi_r,
|
||||
BUF *ni, BUF *nr);
|
||||
|
||||
bool IKEv2ParseSAProposalIKE(void *data, UINT size, IKEv2_IKETF *out);
|
||||
bool IKEv2ParseSAProposalChild(void *data, UINT size, IKEv2_CHILDTF *out, UINT *out_spi_i);
|
||||
UINT IKEv2BuildSAProposalIKE(IKEv2_SA *sa, void *buf, UINT buf_size);
|
||||
UINT IKEv2BuildSAProposalChild(IKEv2_CHILDTF *ctf, UINT spi_r, void *buf, UINT buf_size);
|
||||
|
||||
void IKEv2SendResponse(IKE_SERVER *ike, IKEv2_SA *sa, IKE_HEADER *req_hdr,
|
||||
UCHAR exchange_type, void *payloads, UINT payloads_size,
|
||||
bool encrypt);
|
||||
void IKEv2SendNotifyError(IKE_SERVER *ike, UDPPACKET *p, IKE_HEADER *hdr,
|
||||
UINT64 resp_spi, USHORT notify_type);
|
||||
|
||||
BUF *IKEv2EncryptSK(IKE_SERVER *ike, IKEv2_SA *sa, UCHAR next_payload,
|
||||
void *inner, UINT inner_size);
|
||||
BUF *IKEv2DecryptSK(IKE_SERVER *ike, IKEv2_SA *sa, bool is_init_sending,
|
||||
void *sk_data, UINT sk_size);
|
||||
|
||||
UINT IKEv2PrfKeyLen(UINT prf_alg);
|
||||
UINT IKEv2PrfOutLen(UINT prf_alg);
|
||||
UINT IKEv2IntegKeyLen(UINT integ_alg);
|
||||
UINT IKEv2IntegIcvLen(UINT integ_alg);
|
||||
UINT IKEv2EncrKeyLen(UINT encr_alg, UINT requested);
|
||||
UINT IKEv2EncrBlockSize(UINT encr_alg);
|
||||
IKE_HASH *IKEv2GetHashForPrf(IKE_SERVER *ike, UINT prf_alg);
|
||||
IKE_HASH *IKEv2GetHashForInteg(IKE_SERVER *ike, UINT integ_alg);
|
||||
IKE_CRYPTO *IKEv2GetCrypto(IKE_SERVER *ike, UINT encr_alg);
|
||||
IKE_DH *IKEv2GetDh(IKE_SERVER *ike, UINT dh_group);
|
||||
|
||||
#endif // PROTO_IKEV2_H
|
||||
@@ -2562,9 +2562,16 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
|
||||
Debug("OpenVPN Channel %u Failed.\n", j);
|
||||
OvsLog(s, se, c, "LO_CHANNEL_FAILED");
|
||||
|
||||
if ((se->IpcAsync->ErrorCode == ERR_AUTHTYPE_NOT_SUPPORTED) ||
|
||||
(se->IpcAsync->ErrorCode == ERR_AUTH_FAILED) ||
|
||||
(se->IpcAsync->ErrorCode == ERR_PROXY_AUTH_FAILED) ||
|
||||
(se->IpcAsync->ErrorCode == ERR_USER_AUTHTYPE_NOT_PASSWORD) ||
|
||||
(se->IpcAsync->ErrorCode == ERR_NOT_SUPPORTED_AUTH_ON_OPENSOURCE))
|
||||
{
|
||||
// Return the AUTH_FAILED
|
||||
str = "AUTH_FAILED";
|
||||
WriteFifo(c->SslPipe->SslInOut->SendFifo, str, StrSize(str));
|
||||
}
|
||||
|
||||
s->SessionEstablishedCount++;
|
||||
|
||||
|
||||
+19
-1
@@ -5429,7 +5429,7 @@ void ClientUploadNoop(CONNECTION *c)
|
||||
}
|
||||
|
||||
p = PackError(0);
|
||||
PackAddInt(p, "noop", 1);
|
||||
PackAddInt(p, "noop", NOOP);
|
||||
(void)HttpClientSend(c->FirstSock, p);
|
||||
FreePack(p);
|
||||
|
||||
@@ -5440,6 +5440,24 @@ void ClientUploadNoop(CONNECTION *c)
|
||||
}
|
||||
}
|
||||
|
||||
void ServerUploadNoop(CONNECTION *c)
|
||||
{
|
||||
PACK *p;
|
||||
// Validate arguments
|
||||
if (c == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p = PackError(0);
|
||||
PackAddInt(p, "noop", NOOP_IGNORE);
|
||||
(void)HttpServerSend(c->FirstSock, p);
|
||||
FreePack(p);
|
||||
|
||||
// Client can't re-respond to an HTTP "response"
|
||||
// so we don't wait for it on the server side
|
||||
}
|
||||
|
||||
// Add client version information to the PACK
|
||||
void PackAddClientVersion(PACK *p, CONNECTION *c)
|
||||
{
|
||||
|
||||
@@ -169,6 +169,7 @@ bool GetSessionKeyFromPack(PACK *p, UCHAR *session_key, UINT *session_key_32);
|
||||
void CreateNodeInfo(NODE_INFO *info, CONNECTION *c);
|
||||
UINT SecureSign(SECURE_SIGN *sign, UINT device_id, char *pin);
|
||||
void ClientUploadNoop(CONNECTION *c);
|
||||
void ServerUploadNoop(CONNECTION *c);
|
||||
bool ClientCheckServerCert(CONNECTION *c, bool *expired);
|
||||
void ClientCheckServerCertThread(THREAD *thread, void *param);
|
||||
bool ClientSecureSign(CONNECTION *c, UCHAR *sign, UCHAR *random, X **x);
|
||||
|
||||
+15
-4
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "Radius.h"
|
||||
|
||||
#include "Protocol.h"
|
||||
#include "Connection.h"
|
||||
#include "IPC.h"
|
||||
#include "Server.h"
|
||||
@@ -1767,7 +1768,7 @@ LABEL_ERROR:
|
||||
////////// Classical implementation
|
||||
|
||||
// Attempts Radius authentication (with specifying retry interval and multiple server)
|
||||
bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UCHAR *mschap_v2_server_response_20,
|
||||
bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UINT timeout, UCHAR *mschap_v2_server_response_20,
|
||||
RADIUS_LOGIN_OPTION *opt, char *hubname)
|
||||
{
|
||||
UCHAR random[MD5_SIZE];
|
||||
@@ -2072,14 +2073,22 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
|
||||
|
||||
// Transmission process start
|
||||
start = Tick64();
|
||||
|
||||
// Limit timeout to be larger than hardcoded timeout
|
||||
// Limit interval to be larger than the hardcoded interval and less than timeout
|
||||
if (timeout < RADIUS_RETRY_TIMEOUT) {
|
||||
timeout = RADIUS_RETRY_TIMEOUT;
|
||||
}
|
||||
|
||||
if(interval < RADIUS_RETRY_INTERVAL)
|
||||
{
|
||||
interval = RADIUS_RETRY_INTERVAL;
|
||||
}
|
||||
else if(interval > RADIUS_RETRY_TIMEOUT)
|
||||
else if(interval > timeout)
|
||||
{
|
||||
interval = RADIUS_RETRY_TIMEOUT;
|
||||
interval = timeout;
|
||||
}
|
||||
|
||||
next_send_time = start + (UINT64)interval;
|
||||
|
||||
while (true)
|
||||
@@ -2099,6 +2108,8 @@ SEND_RETRY:
|
||||
next_send_time = Tick64() + (UINT64)interval;
|
||||
|
||||
RECV_RETRY:
|
||||
ServerUploadNoop(c);
|
||||
|
||||
now = Tick64();
|
||||
if (next_send_time <= now)
|
||||
{
|
||||
@@ -2109,7 +2120,7 @@ RECV_RETRY:
|
||||
goto SEND_RETRY;
|
||||
}
|
||||
|
||||
if ((start + RADIUS_RETRY_TIMEOUT) < now)
|
||||
if ((start + timeout) < now)
|
||||
{
|
||||
// Time-out
|
||||
break;
|
||||
|
||||
+1
-1
@@ -283,7 +283,7 @@ struct RADIUS_LOGIN_OPTION
|
||||
};
|
||||
|
||||
// Function prototype
|
||||
bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UCHAR *mschap_v2_server_response_20,
|
||||
bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UINT timeout, UCHAR *mschap_v2_server_response_20,
|
||||
RADIUS_LOGIN_OPTION *opt, char *hubname);
|
||||
BUF *RadiusEncryptPassword(char *password, UCHAR *random, UCHAR *secret, UINT secret_size);
|
||||
BUF *RadiusCreateUserName(wchar_t *username);
|
||||
|
||||
+3
-2
@@ -516,6 +516,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
char suffix_filter[MAX_SIZE];
|
||||
wchar_t suffix_filter_w[MAX_SIZE];
|
||||
UINT interval;
|
||||
UINT timeout;
|
||||
EAP_CLIENT *eap = NULL;
|
||||
char password1[MAX_SIZE];
|
||||
UCHAR client_challenge[16];
|
||||
@@ -586,7 +587,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
}
|
||||
|
||||
// Get the Radius server information
|
||||
if (GetRadiusServerEx2(hub, radius_server_addr, sizeof(radius_server_addr), &radius_server_port, radius_secret, sizeof(radius_secret), &interval, suffix_filter, sizeof(suffix_filter)))
|
||||
if (GetRadiusServerEx3(hub, radius_server_addr, sizeof(radius_server_addr), &radius_server_port, radius_secret, sizeof(radius_secret), &interval, &timeout, suffix_filter, sizeof(suffix_filter)))
|
||||
{
|
||||
Unlock(hub->lock);
|
||||
|
||||
@@ -597,7 +598,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
// Attempt to login
|
||||
b = RadiusLogin(c, radius_server_addr, radius_server_port,
|
||||
radius_secret, StrLen(radius_secret),
|
||||
name, password, interval, mschap_v2_server_response_20, opt, hub->Name);
|
||||
name, password, interval, timeout, mschap_v2_server_response_20, opt, hub->Name);
|
||||
|
||||
if (b)
|
||||
{
|
||||
|
||||
+8
-1
@@ -4855,6 +4855,7 @@ void SiWriteHubCfg(FOLDER *f, HUB *h)
|
||||
}
|
||||
CfgAddInt(f, "RadiusServerPort", h->RadiusServerPort);
|
||||
CfgAddInt(f, "RadiusRetryInterval", h->RadiusRetryInterval);
|
||||
CfgAddInt(f, "RadiusRetryTimeout", h->RadiusRetryTimeout);
|
||||
CfgAddStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter);
|
||||
CfgAddStr(f, "RadiusRealm", h->RadiusRealm);
|
||||
|
||||
@@ -5020,9 +5021,11 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)
|
||||
BUF *secret;
|
||||
UINT port;
|
||||
UINT interval;
|
||||
UINT timeout;
|
||||
|
||||
port = CfgGetInt(f, "RadiusServerPort");
|
||||
interval = CfgGetInt(f, "RadiusRetryInterval");
|
||||
timeout = CfgGetInt(f, "RadiusRetryTimeout");
|
||||
|
||||
CfgGetStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter, sizeof(h->RadiusSuffixFilter));
|
||||
CfgGetStr(f, "RadiusRealm", h->RadiusRealm, sizeof(h->RadiusRealm));
|
||||
@@ -5035,6 +5038,10 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)
|
||||
interval = RADIUS_RETRY_INTERVAL;
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
timeout = RADIUS_RETRY_TIMEOUT;
|
||||
}
|
||||
|
||||
if (port != 0 && CfgGetStr(f, "RadiusServerName", name, sizeof(name)))
|
||||
{
|
||||
secret = CfgGetBuf(f, "RadiusSecret");
|
||||
@@ -5048,7 +5055,7 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)
|
||||
}
|
||||
secret_str[sizeof(secret_str) - 1] = 0;
|
||||
//SetRadiusServer(h, name, port, secret_str);
|
||||
SetRadiusServerEx(h, name, port, secret_str, interval);
|
||||
SetRadiusServerEx2(h, name, port, secret_str, interval, timeout);
|
||||
FreeBuf(secret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4761,7 +4761,7 @@ static void MY_SHA0_Transform(MY_SHA0_CTX* ctx) {
|
||||
UCHAR* p = ctx->buf;
|
||||
int t;
|
||||
for(t = 0; t < 16; ++t) {
|
||||
UINT tmp = *p++ << 24;
|
||||
UINT tmp = (UINT)*p++ << 24;
|
||||
tmp |= *p++ << 16;
|
||||
tmp |= *p++ << 8;
|
||||
tmp |= *p++;
|
||||
|
||||
+26
-2
@@ -1207,12 +1207,14 @@ PACK *HttpClientRecv(SOCK *s)
|
||||
UINT size;
|
||||
UCHAR *tmp;
|
||||
HTTP_VALUE *v;
|
||||
UINT num_noop = 0;
|
||||
// Validate arguments
|
||||
if (s == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
START:
|
||||
h = RecvHttpHeader(s);
|
||||
if (h == NULL)
|
||||
{
|
||||
@@ -1257,6 +1259,22 @@ PACK *HttpClientRecv(SOCK *s)
|
||||
p = BufToPack(b);
|
||||
FreeBuf(b);
|
||||
|
||||
// Client shouldn't receive a noop other than NOOP_IGNORE
|
||||
// because it can't respond without a full new HTTP request
|
||||
UINT noop = PackGetInt(p, "noop");
|
||||
if (noop == NOOP_IGNORE) {
|
||||
Debug("recv: noop ignore\n");
|
||||
FreePack(p);
|
||||
|
||||
num_noop++;
|
||||
|
||||
if (num_noop > MAX_NOOP_PER_SESSION)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
goto START;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1365,13 +1383,14 @@ START:
|
||||
FreeBuf(b);
|
||||
|
||||
// Determine whether it's a NOOP
|
||||
if (PackGetInt(p, "noop") != 0)
|
||||
UINT noop = PackGetInt(p, "noop");
|
||||
if (noop == NOOP)
|
||||
{
|
||||
Debug("recv: noop\n");
|
||||
FreePack(p);
|
||||
|
||||
p = PackError(0);
|
||||
PackAddInt(p, "noop", 1);
|
||||
PackAddInt(p, "noop", NOOP_IGNORE);
|
||||
if (HttpServerSend(s, p) == false)
|
||||
{
|
||||
FreePack(p);
|
||||
@@ -1387,6 +1406,11 @@ START:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
goto START;
|
||||
} else if (noop == NOOP_IGNORE) {
|
||||
Debug("recv: noop ignore\n");
|
||||
FreePack(p);
|
||||
|
||||
goto START;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ static int ydays[] =
|
||||
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
|
||||
};
|
||||
|
||||
static UINT current_num_thread = 0;
|
||||
static COUNTER *current_num_thread = NULL;
|
||||
static UINT cached_number_of_cpus = 0;
|
||||
|
||||
|
||||
@@ -776,6 +776,7 @@ void InitThreading()
|
||||
{
|
||||
thread_pool = NewSk();
|
||||
thread_count = NewCounter();
|
||||
current_num_thread = NewCounter();
|
||||
}
|
||||
|
||||
// Release of thread pool
|
||||
@@ -821,6 +822,9 @@ void FreeThreading()
|
||||
|
||||
DeleteCounter(thread_count);
|
||||
thread_count = NULL;
|
||||
|
||||
DeleteCounter(current_num_thread);
|
||||
current_num_thread = NULL;
|
||||
}
|
||||
|
||||
// Thread pool procedure
|
||||
@@ -1028,9 +1032,9 @@ THREAD *NewThreadNamed(THREAD_PROC *thread_proc, void *param, char *name)
|
||||
|
||||
Wait(pd->InitFinishEvent, INFINITE);
|
||||
|
||||
current_num_thread++;
|
||||
Inc(current_num_thread);
|
||||
|
||||
// Debug("current_num_thread = %u\n", current_num_thread);
|
||||
// Debug("current_num_thread = %u\n", Count(current_num_thread));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1055,8 +1059,8 @@ void CleanupThread(THREAD *t)
|
||||
|
||||
Free(t);
|
||||
|
||||
current_num_thread--;
|
||||
//Debug("current_num_thread = %u\n", current_num_thread);
|
||||
Dec(current_num_thread);
|
||||
//Debug("current_num_thread = %u\n", Count(current_num_thread));
|
||||
}
|
||||
|
||||
// Release thread (pool)
|
||||
|
||||
+16
-1
@@ -72,11 +72,26 @@ int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, char *CmdLine, int CmdShow)
|
||||
|
||||
// Compiler dependent
|
||||
#ifndef OS_WIN32
|
||||
// Gcc compiler
|
||||
// GCC or Clang compiler
|
||||
#define GCC_PACKED __attribute__ ((__packed__))
|
||||
// Clang compiler
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(thread_sanitizer)
|
||||
#define ATTRIBUTE_NO_TSAN __attribute__((no_sanitize("thread")))
|
||||
#endif // __has_feature(thread_sanitizer)
|
||||
#endif // __has_feature
|
||||
// GCC compiler
|
||||
#if defined(__SANITIZE_THREAD__) && !defined(ATTRIBUTE_NO_TSAN)
|
||||
#define ATTRIBUTE_NO_TSAN __attribute__((no_sanitize("thread")))
|
||||
#endif // __SANITIZE_THREAD__
|
||||
// Other or older Clang/GCC compiler
|
||||
#ifndef ATTRIBUTE_NO_TSAN
|
||||
#define ATTRIBUTE_NO_TSAN
|
||||
#endif // ATTRIBUTE_NO_TSAN
|
||||
#else // OS_WIN32
|
||||
// VC++ compiler
|
||||
#define GCC_PACKED
|
||||
#define ATTRIBUTE_NO_TSAN
|
||||
#endif // OS_WIN32
|
||||
|
||||
// Macro that displays the current file name and line number
|
||||
|
||||
@@ -881,8 +881,6 @@ struct SSL_VERIFY_OPTION
|
||||
X *SavedCert; // Saved server certificate
|
||||
};
|
||||
|
||||
#define SSL_DEFAULT_CONNECT_TIMEOUT (15 * 1000) // SSL default timeout
|
||||
|
||||
// Header for TCP Pair
|
||||
struct TCP_PAIR_HEADER
|
||||
{
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
|
||||
// The number of allowable NOOP
|
||||
#define MAX_NOOP_PER_SESSION 30
|
||||
#define NOOP 1
|
||||
#define NOOP_IGNORE 2 // A noop, but don't send a response noop
|
||||
|
||||
// VALUE object
|
||||
struct VALUE
|
||||
|
||||
@@ -470,6 +470,7 @@ LIST *LoadLangList()
|
||||
b = ReadDump(filename);
|
||||
if (b == NULL)
|
||||
{
|
||||
FreeLangList(o);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -651,6 +651,15 @@ struct IKE_HEADER
|
||||
#define IKE_EXCHANGE_TYPE_INFORMATION 5 // Information exchange
|
||||
#define IKE_EXCHANGE_TYPE_QUICK 32 // Quick mode
|
||||
|
||||
// IKEv2 version identifier (in the Version field of IKE_HEADER)
|
||||
#define IKEv2_VERSION 0x20 // 2.0
|
||||
|
||||
// IKEv2 exchange types (RFC 7296)
|
||||
#define IKEv2_EXCHANGE_IKE_SA_INIT 34
|
||||
#define IKEv2_EXCHANGE_IKE_AUTH 35
|
||||
#define IKEv2_EXCHANGE_CREATE_CHILD_SA 36
|
||||
#define IKEv2_EXCHANGE_INFORMATIONAL 37
|
||||
|
||||
// DHCPv4 data
|
||||
struct DHCPV4_DATA
|
||||
{
|
||||
|
||||
@@ -2140,9 +2140,13 @@ void UnixMemoryFree(void *addr)
|
||||
// SIGCHLD handler
|
||||
void UnixSigChldHandler(int sig)
|
||||
{
|
||||
int old_errno = errno;
|
||||
|
||||
// Recall the zombie processes
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0);
|
||||
signal(SIGCHLD, UnixSigChldHandler);
|
||||
|
||||
errno = old_errno;
|
||||
}
|
||||
|
||||
// Disable core dump
|
||||
|
||||
+382
-287
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
# This file contains suppressions for Thread Sanitizer.
|
||||
# For the specification, refer to: https://github.com/google/sanitizers/wiki/threadsanitizersuppressions
|
||||
|
||||
|
||||
|
||||
## Set/Wait
|
||||
# This provides synchronization equivalent to a lock, but Thread Sanitizer cannot recognize it.
|
||||
|
||||
# Thread Sanitizer reports data race on Halt in TK64.
|
||||
# https://github.com/SoftEtherVPN/SoftEtherVPN/pull/2221
|
||||
race_top:FreeTick64
|
||||
|
||||
# Thread Sanitizer reports data races on Finished and NoDelayFlag in CONNECT_SERIAL_PARAM,
|
||||
# shared between BindConnectThreadForIPv4, BindConnectThreadForIPv6, and BindConnectEx5.
|
||||
# https://github.com/SoftEtherVPN/SoftEtherVPN/pull/2222
|
||||
race_top:BindConnectThreadForIPv4
|
||||
race_top:BindConnectThreadForIPv6
|
||||
race_top:BindConnectEx5
|
||||
|
||||
|
||||
## Manual PTHREAD_MUTEX_RECURSIVE
|
||||
# The Lock/Unlock mechanism on Unix is a manual, hand-coded implementation of PTHREAD_MUTEX_RECURSIVE.
|
||||
# We avoid using the PTHREAD_MUTEX_RECURSIVE directly because it exhibits critical bugs, such as deadlocks
|
||||
# on certain older systems(Linux, Solaris, or macOS). While Thread Sanitizer will report data races,
|
||||
# these warnings should be ignored as the logic has been carefully implemented to ensure thread safety.
|
||||
# https://github.com/SoftEtherVPN/SoftEtherVPN/pull/2219
|
||||
race_top:UnixLock
|
||||
race_top:UnixUnlockEx
|
||||
Reference in New Issue
Block a user