OCT 1. 增加 Windows PowerShell NAT 网关开关自定义命令

2. 增加文件 Hash 计算接口
This commit is contained in:
黄昕 2023-06-27 10:02:02 +08:00
parent 37c23698b4
commit afebbff692
18 changed files with 663 additions and 130 deletions

View File

@ -76,12 +76,6 @@
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_DDDEC90D22B81D6B9D637B1C197520B4"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_9C849F5EE1DB4634B3B8ABAEAD8840E3"
"MsmSig" = "8:_UNDEFINED"
}
@ -91,6 +85,12 @@
"OwnerKey" = "8:_92E0C26999D59D33D0500624357FF7A1"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_DDDEC90D22B81D6B9D637B1C197520B4"
"MsmSig" = "8:_UNDEFINED"
}
}
"Configurations"
{
@ -109,6 +109,27 @@
"PrivateKeyFile" = "8:"
"TimeStampServer" = "8:"
"InstallerBootstrapper" = "3:2"
"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
{
"Enabled" = "11:TRUE"
"PromptEnabled" = "11:TRUE"
"PrerequisitesLocation" = "2:1"
"Url" = "8:"
"ComponentsUrl" = "8:"
"Items"
{
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
{
"Name" = "8:Microsoft .NET Framework 4.7.2 (x86 和 x64)"
"ProductCode" = "8:.NETFramework,Version=v4.7.2"
}
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Visual.C++.14.0.x64"
{
"Name" = "8:Visual C++ \"14\" Runtime Libraries (x64)"
"ProductCode" = "8:Microsoft.Visual.C++.14.0.x64"
}
}
}
}
"Release"
{
@ -125,6 +146,14 @@
"PrivateKeyFile" = "8:"
"TimeStampServer" = "8:"
"InstallerBootstrapper" = "3:2"
"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
{
"Enabled" = "11:TRUE"
"PromptEnabled" = "11:TRUE"
"PrerequisitesLocation" = "2:1"
"Url" = "8:"
"ComponentsUrl" = "8:"
}
}
}
"Deployable"
@ -230,7 +259,7 @@
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"Exclude" = "11:TRUE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}

Binary file not shown.

Binary file not shown.

View File

@ -152,11 +152,14 @@
<ClInclude Include="globalcfg.h" />
<ClInclude Include="misc.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="tunnel.h" />
<ClInclude Include="usrerr.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="crypto.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="hashdigest.cpp" />
<ClCompile Include="misc.cpp" />
<ClCompile Include="network.cpp" />
<ClCompile Include="pch.cpp">
@ -174,6 +177,11 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="ps1\wireguard.psm1" />
<None Include="txt1.bin" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="NetTunnelSDK.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -13,6 +13,9 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="源文件\crypto">
<UniqueIdentifier>{1111b68b-34f2-49fa-8116-de5ae65603b6}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h">
@ -36,6 +39,9 @@
<ClInclude Include="AIGCJson.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@ -56,8 +62,23 @@
<ClCompile Include="network.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="hashdigest.cpp">
<Filter>源文件\crypto</Filter>
</ClCompile>
<ClCompile Include="crypto.cpp">
<Filter>源文件\crypto</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="txt1.bin">
<Filter>资源文件</Filter>
</None>
<None Include="ps1\wireguard.psm1" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="NetTunnelSDK.rc">
<Filter>资源文件</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

9
NetTunnelSDK/crypto.cpp Normal file
View File

@ -0,0 +1,9 @@
#include "pch.h"
#include "tunnel.h"
#include "usrerr.h"
#include "misc.h"
#include <strsafe.h>
#include <bcrypt.h>
#include <spdlog/spdlog.h>

View File

@ -22,6 +22,7 @@ typedef struct {
* @brief SDK
*/
typedef struct {
TCHAR systemDirectory[MAX_PATH]; ///< 操作系统目录
TCHAR workDirectory[MAX_PATH]; ///< SDK 当前工作目录
PROTO_CRYPTO_TYPE proCryptoType; ///< 协议加密类型
TCHAR proKeyBuf[256]; ///< 协议加密秘钥

159
NetTunnelSDK/hashdigest.cpp Normal file
View File

@ -0,0 +1,159 @@
#include "pch.h"
#include "tunnel.h"
#include "usrerr.h"
#include "misc.h"
#include <bcrypt.h>
#include <shlwapi.h>
#include <spdlog/spdlog.h>
#pragma comment(lib, "Bcrypt.lib")
//#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define NT_FAILED(s) (((NTSTATUS)(s)) < 0)
//#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
static const LPCWSTR g_BcryptHash[] = {
BCRYPT_MD2_ALGORITHM,
BCRYPT_MD4_ALGORITHM,
BCRYPT_MD5_ALGORITHM,
BCRYPT_SHA1_ALGORITHM,
BCRYPT_SHA256_ALGORITHM,
BCRYPT_SHA384_ALGORITHM,
BCRYPT_SHA512_ALGORITHM,
};
int CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]) {
HANDLE hFile;
BYTE rgbFile[1024];
DWORD cbRead = 0;
BCRYPT_ALG_HANDLE hAlg = nullptr;
BCRYPT_HASH_HANDLE hHash = nullptr;
NTSTATUS status;
DWORD cbData = 0, cbHash = 0, cbHashObject = 0;
PBYTE pbHashObject;
PBYTE pbHash;
if (pPath == nullptr) {
SPDLOG_ERROR("Input pPath params error: {0}", pPath);
return -ERR_INPUT_PARAMS;
}
if (!PathFileExists(pPath)) {
SPDLOG_ERROR("File \'{0}\' not found.", pPath);
return -ERR_ITEM_UNEXISTS;
}
hFile = CreateFile(pPath,
GENERIC_READ,
FILE_SHARE_READ,
nullptr,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
nullptr);
if (INVALID_HANDLE_VALUE == hFile) {
SPDLOG_ERROR("Error opening file %s\nError: {0}", pPath, GetLastError());
return -ERR_OPEN_FILE;
}
//open an algorithm handle
if (NT_FAILED(status = BCryptOpenAlgorithmProvider(&hAlg, g_BcryptHash[type], nullptr, 0))) {
SPDLOG_ERROR(TEXT("Error {0} returned by BCryptOpenAlgorithmProvider"), status);
CloseHandle(hFile);
return -ERR_BCRYPT_OPEN;
}
//calculate the size of the buffer to hold the hash object
if (NT_FAILED(status = BCryptGetProperty(hAlg,
BCRYPT_OBJECT_LENGTH,
reinterpret_cast<PBYTE>(&cbHashObject),
sizeof(DWORD),
&cbData,
0))) {
SPDLOG_ERROR(TEXT("Error {0} returned by BCryptGetProperty"), status);
CloseHandle(hFile);
BCryptCloseAlgorithmProvider(hAlg, 0);
return -ERR_BCRYPT_GETPROPERTY;
}
//allocate the hash object on the heap
pbHashObject = static_cast<PBYTE>(HeapAlloc(GetProcessHeap(), 0, cbHashObject));
if (nullptr == pbHashObject) {
SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), cbHashObject);
CloseHandle(hFile);
BCryptCloseAlgorithmProvider(hAlg, 0);
return -ERR_MALLOC_MEMORY;
}
//calculate the length of the hash
if (NT_FAILED(status = BCryptGetProperty(hAlg,
BCRYPT_HASH_LENGTH,
reinterpret_cast<PBYTE>(&cbHash),
sizeof(DWORD),
&cbData,
0))) {
SPDLOG_ERROR(TEXT("Error {0} returned by BCryptGetProperty"), status);
CloseHandle(hFile);
BCryptCloseAlgorithmProvider(hAlg, 0);
HeapFree(GetProcessHeap(), 0, pbHashObject);
return -ERR_BCRYPT_GETPROPERTY;
}
//allocate the hash buffer on the heap
pbHash = static_cast<PBYTE>(HeapAlloc(GetProcessHeap(), 0, cbHash));
if (nullptr == pbHash) {
SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), cbHash);
CloseHandle(hFile);
BCryptCloseAlgorithmProvider(hAlg, 0);
HeapFree(GetProcessHeap(), 0, pbHashObject);
return -ERR_MALLOC_MEMORY;
}
//create a hash
if (NT_FAILED(status = BCryptCreateHash(hAlg, &hHash, pbHashObject, cbHashObject, nullptr, 0, 0))) {
SPDLOG_ERROR(TEXT("Error {0} returned by BCryptCreateHash"), status);
CloseHandle(hFile);
BCryptCloseAlgorithmProvider(hAlg, 0);
HeapFree(GetProcessHeap(), 0, pbHashObject);
HeapFree(GetProcessHeap(), 0, pbHash);
return -ERR_BCRYPT_CREATEHASH;
}
while (ReadFile(hFile, rgbFile, 1024, &cbRead, nullptr)) {
if (0 == cbRead) {
break;
}
if (NT_FAILED(status = BCryptHashData(hHash, rgbFile, cbRead, 0))) {
SPDLOG_ERROR(TEXT("Error {0} returned by BCryptHashData"), status);
CloseHandle(hFile);
BCryptCloseAlgorithmProvider(hAlg, 0);
BCryptDestroyHash(hHash);
HeapFree(GetProcessHeap(), 0, pbHashObject);
HeapFree(GetProcessHeap(), 0, pbHash);
return -ERR_BCRYPT_HASHDATA;
}
}
//close the hash
if (NT_FAILED(status = BCryptFinishHash(hHash, pbHash, cbHash, 0))) {
SPDLOG_ERROR(TEXT("Error {0} returned by BCryptFinishHash"), status);
CloseHandle(hFile);
BCryptCloseAlgorithmProvider(hAlg, 0);
BCryptDestroyHash(hHash);
HeapFree(GetProcessHeap(), 0, pbHashObject);
HeapFree(GetProcessHeap(), 0, pbHash);
return -ERR_BCRYPT_FINISHHASH;
}
binToHexString(outHash, pbHash, cbHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
BCryptDestroyHash(hHash);
HeapFree(GetProcessHeap(), 0, pbHashObject);
HeapFree(GetProcessHeap(), 0, pbHash);
CloseHandle(hFile);
return ERR_SUCCESS;
}

View File

@ -1,10 +1,24 @@
#include "pch.h"
#include "misc.h"
#include "usrerr.h"
#include <strsafe.h>
#include <spdlog/spdlog.h>
TCHAR *binToHexString(TCHAR *p, const unsigned char *cp, unsigned int count) {
static const TCHAR hex_asc[] = TEXT("0123456789abcdef");
while (count) {
const unsigned char c = *cp++;
/* put lowercase hex digits */
*p++ = static_cast<TCHAR>(0x20 | hex_asc[c >> 4]);
*p++ = static_cast<TCHAR>(0x20 | hex_asc[c & 0xf]);
count--;
}
return p;
}
void RemoveTailLineBreak(TCHAR *pInputStr, int strSize) {
size_t length;
if (pInputStr) {
@ -25,7 +39,7 @@ int RunCommand(TCHAR *pszCmd, TCHAR *pszResultBuffer, int dwResultBufferSize, un
DWORD retCode;
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES securityAttributes = {};
SECURITY_ATTRIBUTES securityAttributes;
if (pszCmd == nullptr) {
SPDLOG_ERROR(TEXT("Input params Error: [{0}]"), pszCmd);

View File

@ -24,9 +24,10 @@ int __cdecl NetmaskToCIDR(const TCHAR *pNetMask);
*/
const TCHAR *CIDRToNetmask(const UINT8 cidr);
void ShowWindowsErrorMessage(const TCHAR *pMsgHead);
void StringReplaceAll(TCHAR *pOrigin, const TCHAR *pOldStr, const TCHAR *pNewStr);
void StringRemoveAll(TCHAR *pOrigin, const TCHAR *pString);
void ShowWindowsErrorMessage(const TCHAR *pMsgHead);
void StringReplaceAll(TCHAR *pOrigin, const TCHAR *pOldStr, const TCHAR *pNewStr);
void StringRemoveAll(TCHAR *pOrigin, const TCHAR *pString);
TCHAR *binToHexString(TCHAR *p, const unsigned char *cp, unsigned int count);
#ifdef __cplusplus
}
#endif

View File

@ -423,73 +423,71 @@ int GetAllNICInfo(PNIC_CONTENT pInfo, int *pItemCounts) {
return ERR_SUCCESS;
}
#if 0
int GetAllNICInfo(PNIC_CONTENT pInfo, int *pItemCounts) {
int nRel, id = 0;
IP_ADDR_STRING *pIpAddrString;
PIP_ADAPTER_INFO pIpAdapterInfo;
unsigned long stSize;
int SetInterfacePrivate(const TCHAR *pInterfaceName, bool isPrivate) {
int ret;
TCHAR cmdBuf[MAX_PATH];
DWORD retCode;
if (pItemCounts == nullptr || pInfo == nullptr) {
return -ERR_INPUT_PARAMS;
}
pIpAdapterInfo = new IP_ADAPTER_INFO[NET_CARD_MAX];
stSize = sizeof(IP_ADAPTER_INFO) * NET_CARD_MAX;
// WIN32 API get net card information
nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
if (ERROR_BUFFER_OVERFLOW == nRel) {
delete[] pIpAdapterInfo;
return -ERR_MALLOC_MEMORY;
}
PIP_ADAPTER_INFO cur = pIpAdapterInfo;
while (cur) {
pInfo[id].InterfaceIndex = cur->Index;
StringCbCopy(pInfo[id].NetCardUUID, MAX_ADAPTER_NAME_LENGTH, cur->AdapterName);
StringCbCopy(pInfo[id].NetCardDescription, MAX_ADAPTER_DESCRIPTION_LENGTH, cur->Description);
switch (cur->Type) {
case MIB_IF_TYPE_ETHERNET:
pIpAddrString = &(cur->IpAddressList);
StringCbCopy(pInfo[id].NetCardIpaddr, MAX_IP_LEN - 1, pIpAddrString->IpAddress.String);
StringCbCopy(pInfo[id].NetCardNetmask, MAX_IP_LEN - 1, pIpAddrString->IpMask.String);
break;
case MIB_IF_TYPE_OTHER:
case MIB_IF_TYPE_TOKENRING:
case MIB_IF_TYPE_FDDI:
case MIB_IF_TYPE_PPP:
case MIB_IF_TYPE_LOOPBACK:
case MIB_IF_TYPE_SLIP:
break;
default: // WIFI ,Unknown type
pIpAddrString = &(cur->IpAddressList);
StringCbCopy(pInfo[id].NetCardIpaddr, MAX_IP_LEN - 1, pIpAddrString->IpAddress.String);
StringCbCopy(pInfo[id].NetCardNetmask, MAX_IP_LEN - 1, pIpAddrString->IpMask.String);
break;
if (isPrivate) {
if (FAILED(StringCbPrintf(
cmdBuf,
MAX_PATH,
"PowerShell -Command \"& {Set-NetConnectionProfile -InterfaceAlias %s -NetworkCategory \"Private\"}\"",
pInterfaceName))) {
SPDLOG_ERROR("Format String Error");
return -ERR_MEMORY_STR;
}
} else {
if (FAILED(StringCbPrintf(
cmdBuf,
MAX_PATH,
"PowerShell -Command \"& {Set-NetConnectionProfile -InterfaceAlias %s -NetworkCategory \"Public\"}\"",
pInterfaceName))) {
SPDLOG_ERROR("Format String Error");
return -ERR_MEMORY_STR;
}
StringCbPrintf(pInfo[id].NetCardMacAddr,
20 - 1,
"%02X:%02X:%02X:%02X:%02X:%02X",
cur->Address[0],
cur->Address[1],
cur->Address[2],
cur->Address[3],
cur->Address[4],
cur->Address[5]);
id++;
cur = cur->Next;
}
*pItemCounts = id;
if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) {
SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret);
return -ERR_CALL_SHELL;
}
delete[] pIpAdapterInfo;
if (retCode != 0) {
SPDLOG_ERROR("PowerShell return error({1}): {0}", cmdBuf, retCode);
return -ERR_PROCESS_RETURN;
}
return ERR_SUCCESS;
}
#endif
/**
* @brief WireGuard Windows PowerShell
* @return
* - TRUE
* - FALSE
*/
bool CustomNatPSCmdInstalled() {
TCHAR psCmdPath[MAX_PATH];
StringCbPrintf(psCmdPath,
MAX_PATH,
TEXT("%s\\system32\\WindowsPowerShell\\v1.0\\Modules\\wireguard"),
GetGlobalCfgInfo()->systemDirectory);
// 判断 WireGuard NAT 命令是否安装
if (!PathFileExists(psCmdPath)) {
if (!CreateDirectory(psCmdPath, nullptr)) {
return false;
}
}
StringCbCat(psCmdPath, MAX_PATH, "\\wireguard.psm1");
if (PathFileExists(psCmdPath)) {
// 文件存在说明已经安装
return true;
}
return false;
}

View File

@ -0,0 +1,63 @@
Function Set-NetConnectionSharing
{
Param
(
[Parameter(Mandatory=$true)]
[string]
$LocalConnection,
[Parameter(Mandatory=$true)]
[bool]
$Enabled
)
Begin
{
$netShare = $null
try
{
# Create a NetSharingManager object
$netShare = New-Object -ComObject HNetCfg.HNetShare
}
catch
{
# Register the HNetCfg library (once)
regsvr32 /s hnetcfg.dll
# Create a NetSharingManager object
$netShare = New-Object -ComObject HNetCfg.HNetShare
}
}
Process
{
#Clear Existing Share
$oldConnections = $netShare.EnumEveryConnection |? { $netShare.INetSharingConfigurationForINetConnection.Invoke($_).SharingEnabled -eq $true}
foreach($oldShared in $oldConnections)
{
$oldConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($oldShared)
$oldConfig.DisableSharing()
}
# Find connections
$InternetConnection = Get-NetRoute | ? DestinationPrefix -eq '0.0.0.0/0' | Get-NetIPInterface | Where ConnectionState -eq 'Connected'
$publicConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $InternetConnection.InterfaceAlias }
$privateConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $LocalConnection }
# Get sharing configuration
$publicConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($publicConnection)
$privateConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($privateConnection)
if ($Enabled)
{
$publicConfig.EnableSharing(0)
$privateConfig.EnableSharing(1)
}
else
{
$publicConfig.DisableSharing()
$privateConfig.DisableSharing()
}
}
}

16
NetTunnelSDK/resource.h Normal file
View File

@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 NetTunnelSDK.rc 使用
//
#define IDR_TXT2 102
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,6 +1,7 @@
#include "pch.h"
#include "tunnel.h"
#include <shlobj_core.h>
#include <strsafe.h>
#include <spdlog/sinks/wincolor_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>
@ -30,6 +31,12 @@ int TunnelSDKInitEnv(const TCHAR *pWorkDir) {
spdlog::set_level(spdlog::level::off);
}
if (SUCCEEDED(
SHGetFolderPath(NULL, CSIDL_WINDOWS | CSIDL_FLAG_NO_ALIAS, NULL, 0, g_globalConfig.systemDirectory))) {
SPDLOG_ERROR(TEXT("Get Windows system directory error."));
return -ERR_ITEM_EXISTS;
}
if (pWorkDir == nullptr) {
// 获取当前文件默认路径
GetCurrentDirectory(MAX_PATH, g_globalConfig.workDirectory);
@ -121,12 +128,9 @@ void TunnelLogEnable(bool enLog) {
}
}
int SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR* pProKey)
{
if (type > CRYPTO_BASE64 && type < CRYPTO_MAX)
{
if (pProKey == nullptr || strlen(pProKey) < 8)
{
int SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR *pProKey) {
if (type > CRYPTO_BASE64 && type < CRYPTO_MAX) {
if (pProKey == nullptr || strlen(pProKey) < 8) {
return -ERR_INPUT_PARAMS;
}
}
@ -134,7 +138,8 @@ int SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR* pProKey)
g_globalConfig.proCryptoType = type;
StringCbCopy(g_globalConfig.proKeyBuf, 256, pProKey);
SPDLOG_DEBUG(TEXT("Protocol crypto type: {0} with key [{1}]"), static_cast<int>(type),
SPDLOG_DEBUG(TEXT("Protocol crypto type: {0} with key [{1}]"),
static_cast<int>(type),
pProKey ? pProKey : TEXT(""));
return ERR_SUCCESS;

View File

@ -50,6 +50,20 @@ enum LOG_LEVEL {
LOG_OFF ///< 关闭日志
};
/**
* @brief Hash
*
*/
typedef enum {
HASH_MD2 = 0, ///< MD2 HASH 算法
HASH_MD4, ///< MD4 HASH 算法
HASH_MD5, ///< MD5 HASH 算法
HASH_SHA1, ///< SHA1 HASH 算法
HASH_SHA256, ///< SHA256 HASH 算法
HASH_SHA384, ///< SHA384 HASH 算法
HASH_SHA512 ///< SHA512 HASH 算法
} HASH_TYPE;
/**
*
* @brief
@ -168,7 +182,7 @@ TUNNEL_API int __cdecl GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize,
/**
* @brief WireGuard
* @param pWgConfig @see WGSERVER_CONFIG
* @param[in] pWgConfig @see WGSERVER_CONFIG
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
@ -180,7 +194,7 @@ TUNNEL_API int __cdecl WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgCon
/**
* @brief WireGuard
* @param pWgConfig @see WGCLIENT_CONFIG
* @param[in] pWgConfig @see WGCLIENT_CONFIG
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
@ -197,13 +211,15 @@ TUNNEL_API int __cdecl WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgCon
*/
TUNNEL_API int __cdecl WireGuardInstallServerService(bool bInstall);
TUNNEL_API int __cdecl InstallWindowsNATCommand();
/**
* @brief SDK
*/
TUNNEL_API void __cdecl TunnelSDKUnInit();
/**
* @brief
* @param[in,out] pInfo @see NIC_CONTENT
* @param[out] pInfo @see NIC_CONTENT
* @param[out] pItemCounts 32
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
@ -214,8 +230,8 @@ TUNNEL_API int __cdecl GetAllNICInfo(PNIC_CONTENT pInfo, int *pItemCounts);
/**
* @brief
* @param pInterfaceName
* @param pIndex
* @param[in] pInterfaceName
* @param[out] pIndex
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
@ -289,8 +305,8 @@ TUNNEL_API int __cdecl EnableWindowsHyperV(bool enabled);
/**
* @brief Windows WireGuard NAT
* @param pInterfaceName
* @param pCidrIpaddr CIDR
* @param[in] pInterfaceName
* @param[in] pCidrIpaddr CIDR
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MEMORY_STR
@ -299,6 +315,47 @@ TUNNEL_API int __cdecl EnableWindowsHyperV(bool enabled);
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl SetNATRule(const TCHAR *pInterfaceName, const TCHAR *pCidrIpaddr);
/**
* @brief Private/Public
* @param[in] pInterfaceName
* @param[in] isPrivate
* - TRUE Private
* - FALSE Public
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MEMORY_STR
* - -ERR_CALL_SHELL
* - -ERR_PROCESS_RETURN
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl SetInterfacePrivate(const TCHAR *pInterfaceName, bool isPrivate);
/**
* @brief WireGuard Windows PowerShell
* @return
* - TRUE
* - FALSE
*/
TUNNEL_API bool __cdecl CustomNatPSCmdInstalled();
/**
* @brief Hash
* @param[in] type Hash @see HASH_TYPE
* @param[in] pPath Hash
* @param[out] outHash
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_ITEM_UNEXISTS
* - -ERR_OPEN_FILE
* - -ERR_BCRYPT_OPEN
* - -ERR_BCRYPT_GETPROPERTY
* - -ERR_BCRYPT_CREATEHASH Hash
* - -ERR_BCRYPT_HASHDATA Hash
* - -ERR_BCRYPT_FINISHHASH Hash
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]);
#ifdef __cplusplus
}
#endif

View File

@ -12,6 +12,7 @@ enum USER_ERRNO {
ERR_ITEM_UNEXISTS, ///< 该内容不存在
ERR_SYS_INIT, ///< 系统中断
ERR_SYS_CALL, ///< 系统调用
ERR_CREATE_FILE, ///< 创建文件/目录失败
ERR_OPEN_FILE, ///< 打开文件失败
ERR_READ_FILE, ///< 读取文件失败
ERR_WRITE_FILE, ///< 写入文件失败
@ -23,5 +24,10 @@ enum USER_ERRNO {
ERR_MMAP_MEMORY, ///< 共享内存失败
ERR_MEMORY_STR, ///< 字符串操作失败
ERR_CREATE_PROCESS, ///< 创建进程失败
ERR_PROCESS_RETURN ///< 进程调用返回失败
ERR_PROCESS_RETURN, ///< 进程调用返回失败
ERR_BCRYPT_OPEN, ///< 创建加密算法失败
ERR_BCRYPT_GETPROPERTY, ///< 获取加密算法属性失败
ERR_BCRYPT_CREATEHASH, ///< 创建 Hash 算法失败
ERR_BCRYPT_HASHDATA, ///< 计算 Hash 数据失败
ERR_BCRYPT_FINISHHASH, ///< 计算 Hash 结果失败
};

View File

@ -7,6 +7,7 @@
#include "globalcfg.h"
#include "misc.h"
#include "resource.h"
#pragma comment(lib, "Shlwapi.lib")
@ -17,6 +18,11 @@ constexpr auto WINENVBUF_SIZE = (4096);
#define CFG_WGCFG_PATH TEXT("WgCfgPath")
#define CFG_WG_PATH TEXT("WgExe")
/**
* @brief / WireGuard
* @param[in] bInstall TRUE , FALSE
* @return 0: 0 @see USER_ERRNO
*/
int WireGuardInstallServerService(bool bInstall) {
TCHAR cfgVal[MAX_PATH];
DWORD retCode;
@ -29,10 +35,7 @@ int WireGuardInstallServerService(bool bInstall) {
GetGlobalCfgInfo()->cfgPath);
if (lstrlen(cfgVal) > 0) {
WIN32_FIND_DATA FindFileData;
const HANDLE hFind = FindFirstFile(cfgVal, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
if (PathFileExists(cfgVal)) {
TCHAR cmdBuf[MAX_PATH];
int ret;
@ -76,6 +79,16 @@ int WireGuardInstallServerService(bool bInstall) {
}
}
/**
* @brief WireGuard
* @param[in] pWgConfig @see WGCLIENT_CONFIG
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
* - -ERR_OPEN_FILE
* - -ERR_MEMORY_STR
* - ERR_SUCCESS
*/
int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) {
const size_t bufSize = 4096 * sizeof(TCHAR);
const TCHAR cfgFormat[] = TEXT(
@ -188,6 +201,16 @@ int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) {
return ERR_SUCCESS;
}
/**
* @brief WireGuard
* @param[in] pWgConfig @see WGSERVER_CONFIG
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
* - -ERR_OPEN_FILE
* - -ERR_MEMORY_STR
* - ERR_SUCCESS
*/
int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) {
const size_t bufSize = 4096 * sizeof(TCHAR);
const TCHAR cfgFormat[] = TEXT(
@ -303,6 +326,17 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) {
return ERR_SUCCESS;
}
/**
* @brief WireGuard
* @param[out] pPubKey
* @param[in] pubkeySize ()
* @param[out] pPrivKey
* @param[in] privKeySize ()
* @return 0: 0 @see USER_ERRNO
* - -ERR_ITEM_UNEXISTS WireGuard
* - -ERR_CALL_SHELL
* - ERR_SUCCESS
*/
int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, int privKeySize) {
int ret;
DWORD retCode;
@ -347,17 +381,20 @@ int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, i
return ERR_SUCCESS;
}
/**
* @brief wireguard.exe
* @param[in] pPath wireguard.exe
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_ITEM_UNEXISTS
* - ERR_SUCCESS
*/
int SetWireguardPath(const TCHAR *pPath) {
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
if (pPath == nullptr) {
return -ERR_INPUT_PARAMS;
}
hFind = FindFirstFile(pPath, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
if (PathFileExists(pPath)) {
TCHAR wgPath[MAX_PATH];
SPDLOG_DEBUG(TEXT("Used configure file:{0}"), GetGlobalCfgInfo()->cfgPath);
@ -381,50 +418,76 @@ int SetWireguardPath(const TCHAR *pPath) {
}
}
/**
* @brief WireGuard
* @param[out] pFullPath wireguard.exe
* @param[in] maxSize pFullPath
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
* - -ERR_FILE_NOT_EXISTS
* - ERR_SUCCESS
*/
int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
TCHAR path[MAX_PATH];
TCHAR wrieguardPath[MAX_PATH];
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
DWORD dwRet;
LPSTR pEnvBuf;
TCHAR *token, *p = nullptr;
TCHAR path[MAX_PATH];
TCHAR wireguardPath[MAX_PATH];
DWORD dwRet;
LPSTR pEnvBuf;
TCHAR *token, *p = nullptr;
GetPrivateProfileString(CFG_WIREGUARD_SECTION,
CFG_WIREGUARD_PATH,
TEXT(""),
wrieguardPath,
wireguardPath,
MAX_PATH,
GetGlobalCfgInfo()->cfgPath);
hFind = FindFirstFile(wrieguardPath, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
if (PathFileExists(wireguardPath)) {
if (pFullPath && maxSize > 0) {
StringCbCopy(pFullPath, maxSize, wrieguardPath);
StringCbCopy(pFullPath, maxSize, wireguardPath);
}
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wrieguardPath);
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wireguardPath);
GetGlobalCfgInfo()->wireguardCfg.wireguardExists = TRUE;
SPDLOG_DEBUG(TEXT("Ini found WireGuard at: {0}"), wrieguardPath);
SPDLOG_DEBUG(TEXT("Ini found WireGuard at: {0}"), wireguardPath);
GetPrivateProfileString(CFG_WIREGUARD_SECTION,
CFG_WG_PATH,
TEXT(""),
wrieguardPath,
wireguardPath,
MAX_PATH,
GetGlobalCfgInfo()->cfgPath);
hFind = FindFirstFile(wrieguardPath, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wgPath, MAX_PATH, wrieguardPath);
if (PathFileExists(wireguardPath)) {
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wgPath, MAX_PATH, wireguardPath);
GetGlobalCfgInfo()->wireguardCfg.wgExists = TRUE;
SPDLOG_DEBUG(TEXT("Ini found WireGuard Tools at: {0}"), wrieguardPath);
SPDLOG_DEBUG(TEXT("Ini found WireGuard Tools at: {0}"), wireguardPath);
}
return ERR_SUCCESS;
}
StringCbCopy(wireguardPath, MAX_PATH, GetGlobalCfgInfo()->systemDirectory);
PathStripToRootA(wireguardPath);
StringCbCat(wireguardPath, MAX_PATH, TEXT("Program Files\\WireGuard\\wireguard.exe"));
if (PathFileExists(wireguardPath)) {
// 保存路径到配置文件
SetWireguardPath(wireguardPath);
GetGlobalCfgInfo()->wireguardCfg.wireguardExists = TRUE;
PathRemoveFileSpec(wireguardPath);
StringCbCat(wireguardPath, MAX_PATH, TEXT("\\wg.exe"));
if (PathFileExists(wireguardPath)) {
GetGlobalCfgInfo()->wireguardCfg.wgExists = TRUE;
}
return ERR_SUCCESS;
}
// 从环境变量中查找
pEnvBuf = static_cast<LPSTR>(malloc(WINENVBUF_SIZE));
if (nullptr == pEnvBuf) {
SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), WINENVBUF_SIZE);
@ -442,7 +505,7 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
return -ERR_FILE_NOT_EXISTS;
}
} else if (WINENVBUF_SIZE < dwRet) {
LPSTR pBuf = static_cast<LPSTR>(realloc(pEnvBuf, dwRet * sizeof(CHAR)));
const auto pBuf = static_cast<LPSTR>(realloc(pEnvBuf, dwRet * sizeof(CHAR)));
if (nullptr == pBuf) {
SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), dwRet * sizeof(CHAR));
free(pEnvBuf);
@ -464,9 +527,7 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
memset(path, 0, MAX_PATH);
StringCbPrintfA(path, MAX_PATH, TEXT("%s\\wireguard.exe"), token);
hFind = FindFirstFile(path, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
if (PathFileExists(path)) {
if (pFullPath && maxSize > 0) {
StringCbCopy(pFullPath, maxSize, path);
}
@ -475,7 +536,7 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
SetWireguardPath(path);
SPDLOG_DEBUG(TEXT("Path Environment found WireGuard at: {0}"), path);
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wrieguardPath);
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wireguardPath);
GetGlobalCfgInfo()->wireguardCfg.wireguardExists = TRUE;
memset(path, 0, MAX_PATH);
@ -483,8 +544,7 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
SPDLOG_DEBUG(TEXT("Find WireGuard tools at: {0}"), path);
hFind = FindFirstFile(path, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
if (PathFileExists(path)) {
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wgPath, MAX_PATH, path);
GetGlobalCfgInfo()->wireguardCfg.wgExists = TRUE;
@ -501,4 +561,80 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
free(pEnvBuf);
return -ERR_FILE_NOT_EXISTS;
}
int InstallWindowsNATCommand() {
TCHAR psCmdPath[MAX_PATH];
// 如果已经安装则退出
if (CustomNatPSCmdInstalled()) {
return ERR_SUCCESS;
}
StringCbPrintf(psCmdPath,
MAX_PATH,
TEXT("%s\\system32\\WindowsPowerShell\\v1.0\\Modules\\wireguard\\wireguard.psm1"),
GetGlobalCfgInfo()->systemDirectory);
const HANDLE hFile = CreateFile(psCmdPath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ,
nullptr,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
nullptr);
if (hFile == INVALID_HANDLE_VALUE) {
SPDLOG_ERROR("CreatFile [{0}] error: {1}", psCmdPath, GetLastError());
return -ERR_OPEN_FILE;
}
const HMODULE hMod = GetModuleHandle(TEXT("NetTunnelSDK.dll"));
if (nullptr == hMod) {
SPDLOG_ERROR(TEXT("Load NetTunnelSDK.dll module error"));
::CloseHandle(hFile);
return -ERR_ITEM_UNEXISTS;
}
const HRSRC hRsrc = FindResource(hMod, MAKEINTRESOURCE(IDR_TXT2), TEXT("TXT"));
if (nullptr == hRsrc) {
SPDLOG_ERROR(TEXT("Donot found resource {0} of type {1}"), IDR_TXT2, TEXT("TXT"));
::CloseHandle(hFile);
return -ERR_ITEM_UNEXISTS;
}
const DWORD resSize = SizeofResource(hMod, hRsrc);
if (resSize == 0) {
SPDLOG_ERROR(TEXT("Resource {0} of type {1} is empty"), IDR_TXT2, TEXT("TXT"));
::CloseHandle(hFile);
return -ERR_ITEM_UNEXISTS;
}
const HGLOBAL hGlobal = LoadResource(hMod, hRsrc);
if (hGlobal == hRsrc) {
SPDLOG_ERROR(TEXT("Load resource {0} of type {1} error"), IDR_TXT2, TEXT("TXT"));
::CloseHandle(hFile);
return -ERR_ITEM_UNEXISTS;
}
if (const LPVOID pBuffer = LockResource(hGlobal)) {
if (!WriteFile(hFile, // open file handle
pBuffer, // start of data to write
static_cast<DWORD>(resSize), // number of bytes to write
nullptr, // number of bytes that were written
nullptr)) {
SPDLOG_ERROR("WriteFile [{0}] error: {1}", psCmdPath, GetLastError());
GlobalUnlock(hGlobal);
::CloseHandle(hFile);
return -ERR_OPEN_FILE;
}
}
GlobalUnlock(hGlobal);
::CloseHandle(hFile);
return ERR_SUCCESS;
}

View File

@ -3,6 +3,7 @@
#include "../NetTunnelSDK/tunnel.h"
#include "../NetTunnelSDK/usrerr.h"
#include "../NetTunnelSDK/misc.h"
#include "../NetTunnelSDK/globalcfg.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
@ -11,6 +12,7 @@ TEST_MODULE_INITIALIZE(ModuleInitialize) {
Logger::WriteMessage("In Module Initialize");
TunnelSDKInitEnv(
TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_windows\\NetTunnelApp\\bin\\Debug"));
InitTunnelSDKLog(TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_"
"windows\\NetTunnelApp\\bin\\Debug\\utest.log"),
LOG_DEBUG);
@ -55,15 +57,12 @@ public:
}
TEST_METHOD(TestSetInterfaceIpAddressFromCIDR) {
Assert::AreEqual(
RET_OK,
SetInterfaceIpAddressFromCIDR(TEXT("wg_server"), TEXT("192.168.100.250/24")));
Assert::AreEqual(RET_OK, SetInterfaceIpAddressFromCIDR(TEXT("wg_server"), TEXT("192.168.100.250/24")));
}
TEST_METHOD(TestSetInterfaceIpAddress) {
Assert::AreEqual(
RET_OK,
SetInterfaceIpAddress(TEXT("wg_server"), TEXT("192.168.101.250"), TEXT("255.255.0.0")));
Assert::AreEqual(RET_OK,
SetInterfaceIpAddress(TEXT("wg_server"), TEXT("192.168.101.250"), TEXT("255.255.0.0")));
}
TEST_METHOD(TestGetInterfaceIndexByName) {
@ -71,7 +70,7 @@ public:
Assert::AreEqual(RET_OK, GetInterfaceIndexByName(TEXT("wg_server"), &index));
}
TEST_METHOD(TestRemoveInterfaceIpAddress) {
TEST_METHOD(TestRemoveInterfaceIpAddress) {
Assert::AreEqual(RET_OK, RemoveInterfaceIpAddress(TEXT("wg_server")));
}
@ -80,5 +79,16 @@ public:
Assert::AreEqual(RET_OK, GetWindowsHyperVStatus(&enable));
Assert::AreEqual(TRUE, enable);
}
TEST_METHOD(TestInstallWindowsNATCommand) {
Assert::AreEqual(RET_OK, InstallWindowsNATCommand());
}
TEST_METHOD(TestCalcFileHash) {
TCHAR outHash[MAX_PATH] = {0};
Assert::AreEqual(RET_OK, CalcFileHash(HASH_SHA256, TEXT("E:\\wireguard.psm1"), outHash));
Assert::AreEqual(TEXT("3ef17a2eb23a148a3fbe14cb4ef38747e0a1e5037b6afa2350a9b18f617bb5db"), outHash);
}
};
}