NetTunnelWindows/NetTunnelSDK/wireguard.cpp

231 lines
7.2 KiB
C++

#include "pch.h"
#include "tunnel.h"
#include "usrerr.h"
#include <strsafe.h>
#include <tchar.h>
#include "globalcfg.h"
#include "misc.h"
#define WINENVBUF_SIZE (4096)
#define CONFIG_FILE_NAME TEXT("tunnelsdk.ini")
#define CFG_WIREGUARD_SECTION TEXT("WireGuard")
#define CFG_WIREGUARD_PATH TEXT("WireGuardExe")
#define CFG_WG_PATH TEXT("WgExe")
TUNNEL_API int GenerateWireguardKeyPairs(TCHAR* pPubKey, int pubkeySize, TCHAR* pPrivKey, int privKeySize)
{
int ret;
TCHAR cmdBuffer[MAX_PATH];
TCHAR cmdResult[MAX_PATH];
PSDK_CONFIG pCfg = GetGlobalCfgInfo();
// WireGuard 不存在或者未配置目录
if (!pCfg->wireguardCfg.wgExists || !pCfg->wireguardCfg.wireguardExists)
{
return -ERR_ITEM_UNEXISTS;
}
memset(cmdBuffer, 0, MAX_PATH);
memset(cmdResult, 0, MAX_PATH);
StringCbPrintf(cmdBuffer, MAX_PATH, TEXT("cmd.exe /C \"%s\" genkey"), pCfg->wireguardCfg.wgPath);
if ((ret = RunPipeCmd(cmdBuffer, cmdResult, MAX_PATH)) != ERR_SUCCESS)
{
SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuffer, ret);
return -ERR_CALL_SHELL;
}
SPDLOG_DEBUG("Run command [{0}] resutl \'{1}\'", cmdBuffer, cmdResult);
StringCbCopy(pPrivKey, privKeySize, cmdResult);
memset(cmdBuffer, 0, MAX_PATH);
StringCbPrintf(cmdBuffer, MAX_PATH, TEXT("cmd.exe /C echo %s | \"%s\" pubkey"), cmdResult,
pCfg->wireguardCfg.wgPath);
memset(cmdResult, 0, MAX_PATH);
if ((ret = RunPipeCmd(cmdBuffer, cmdResult, MAX_PATH)) != ERR_SUCCESS)
{
SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuffer, ret);
return -ERR_CALL_SHELL;
}
StringCbCopy(pPubKey, pubkeySize, cmdResult);
SPDLOG_DEBUG("Run command [{0}] resutl \'{1}\'", cmdBuffer, cmdResult);
return ERR_SUCCESS;
}
TUNNEL_API int SetWireguardPath(TCHAR* pPath)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
if (pPath == nullptr)
{
return -ERR_INPUT_PARAMS;
}
hFind = FindFirstFile(pPath, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
TCHAR path[MAX_PATH] = {0};
TCHAR wgPath[MAX_PATH];
StringCbPrintf(path, MAX_PATH, TEXT("%s\\%s"), GetGlobalCfgInfo()->workDirectory, CONFIG_FILE_NAME);
SPDLOG_DEBUG(TEXT("Used configure file:{0}"), path);
WritePrivateProfileString(CFG_WIREGUARD_SECTION, CFG_WIREGUARD_PATH, pPath, path);
SPDLOG_DEBUG(TEXT("Save configure: {1} --> {0}"), pPath, CFG_WIREGUARD_PATH);
StringCbCopy(wgPath, MAX_PATH, pPath);
TCHAR* pIndex = _tcsrchr(wgPath, '\\');
if (pIndex)
{
*pIndex = 0;
StringCbCat(wgPath, MAX_PATH, "\\wg.exe");
WritePrivateProfileString(CFG_WIREGUARD_SECTION, CFG_WG_PATH, wgPath, path);
SPDLOG_DEBUG(TEXT("Save configure: {1} --> {0}"), wgPath, CFG_WG_PATH);
}
return ERR_SUCCESS;
}
else
{
return -ERR_ITEM_UNEXISTS;
}
}
TUNNEL_API int FindWireguardExe(TCHAR* pFullPath, int maxSize)
{
TCHAR path[MAX_PATH];
TCHAR wrieguardPath[MAX_PATH];
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
DWORD dwRet, dwErr;
LPSTR pEnvBuf;
TCHAR *token, *p = nullptr;
memset(path, 0, MAX_PATH);
StringCbPrintf(path, MAX_PATH, TEXT("%s\\%s"), GetGlobalCfgInfo()->workDirectory, CONFIG_FILE_NAME);
GetPrivateProfileString(CFG_WIREGUARD_SECTION,CFG_WIREGUARD_PATH,TEXT(""), wrieguardPath,MAX_PATH, path);
hFind = FindFirstFile(wrieguardPath, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
if (pFullPath && maxSize > 0)
{
StringCbCopy(pFullPath, maxSize, wrieguardPath);
}
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wrieguardPath);
GetGlobalCfgInfo()->wireguardCfg.wireguardExists = TRUE;
SPDLOG_DEBUG(TEXT("Ini found WireGuard at: {0}"), wrieguardPath);
memset(path, 0, MAX_PATH);
StringCbPrintf(path, MAX_PATH, TEXT("%s\\%s"), GetGlobalCfgInfo()->workDirectory, CONFIG_FILE_NAME);
GetPrivateProfileString(CFG_WIREGUARD_SECTION,CFG_WG_PATH,TEXT(""), wrieguardPath,MAX_PATH, path);
hFind = FindFirstFile(wrieguardPath, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wgPath, MAX_PATH, wrieguardPath);
GetGlobalCfgInfo()->wireguardCfg.wgExists = TRUE;
SPDLOG_DEBUG(TEXT("Ini found WireGuard Tools at: {0}"), wrieguardPath);
}
return ERR_SUCCESS;
}
pEnvBuf = static_cast<LPSTR>(malloc(WINENVBUF_SIZE));
if (nullptr == pEnvBuf)
{
SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), WINENVBUF_SIZE);
return -ERR_MALLOC_MEMORY;
}
dwRet = GetEnvironmentVariable(TEXT("path"), pEnvBuf, WINENVBUF_SIZE);
if (0 == dwRet)
{
dwErr = GetLastError();
if (ERROR_ENVVAR_NOT_FOUND == dwErr)
{
SPDLOG_DEBUG(TEXT("Environment variable path does not exist."));
free(pEnvBuf);
return -ERR_FILE_NOT_EXISTS;
}
}
else if (WINENVBUF_SIZE < dwRet)
{
pEnvBuf = static_cast<LPSTR>(realloc(pEnvBuf, dwRet * sizeof(CHAR)));
if (nullptr == pEnvBuf)
{
SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), dwRet * sizeof(CHAR));
return -ERR_MALLOC_MEMORY;
}
dwRet = GetEnvironmentVariable("path", pEnvBuf, dwRet);
if (!dwRet)
{
SPDLOG_ERROR(TEXT("GetEnvironmentVariable failed (%d)"), GetLastError());
free(pEnvBuf);
return -ERR_FILE_NOT_EXISTS;
}
}
token = strtok_s(pEnvBuf, TEXT(";"), &p);
while (token != nullptr)
{
memset(path, 0, MAX_PATH);
StringCbPrintfA(path, MAX_PATH, TEXT("%s\\wireguard.exe"), token);
hFind = FindFirstFile(path, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
if (pFullPath && maxSize > 0)
{
StringCbCopy(pFullPath, maxSize, path);
}
// 保存路径到配置文件
SetWireguardPath(path);
SPDLOG_DEBUG(TEXT("Path Environment found WireGuard at: {0}"), path);
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wrieguardPath);
GetGlobalCfgInfo()->wireguardCfg.wireguardExists = TRUE;
memset(path, 0, MAX_PATH);
StringCbPrintf(path, MAX_PATH, TEXT("%s\\wg.exe"), token);
SPDLOG_DEBUG(TEXT("Find WireGuard tools at: {0}"), path);
hFind = FindFirstFile(path, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wgPath, MAX_PATH, path);
GetGlobalCfgInfo()->wireguardCfg.wgExists = TRUE;
SPDLOG_DEBUG(TEXT("Path Environment found WireGuard tools at: {0}"), path);
}
//TODO: throw exception by C# call, why??????
//CloseHandle(hFind);
free(pEnvBuf);
return ERR_SUCCESS;
}
token = strtok_s(nullptr, TEXT(";"), &p);
}
free(pEnvBuf);
return -ERR_FILE_NOT_EXISTS;
}