#include "pch.h" #include "tunnel.h" #include "usrerr.h" #include "globalcfg.h" #include "httplib.h" #include "misc.h" #include "network.h" #include "protocol.h" #include "user.h" #include #include static HANDLE g_HeartTimerQueue = nullptr; static LPTUNNEL_HEART_ROUTINE g_lpHeartCb = nullptr; int RemoteHeartControl(bool isStart, LPTUNNEL_HEART_ROUTINE lpHeartCbAddress) { if (isStart && lpHeartCbAddress == nullptr) { SPDLOG_ERROR(TEXT("Input lpHeartCbAddress params nullptr")); return -ERR_INPUT_PARAMS; } g_lpHeartCb = lpHeartCbAddress; if (isStart) { if (!g_HeartTimerQueue) { HANDLE hTimer = nullptr; // Create the timer queue. g_HeartTimerQueue = CreateTimerQueue(); if (nullptr == g_HeartTimerQueue) { SPDLOG_ERROR(TEXT("CreateTimerQueue failed ({0})"), GetLastError()); return -ERR_CREATE_TIMER; } // Set a timer to call the timer routine in 10 seconds. if (!CreateTimerQueueTimer( &hTimer, g_HeartTimerQueue, [](PVOID lpParam, BOOLEAN TimerOrWaitFired) { int ret; ProtocolRequest req; ProtocolResponse rsp; ret = ProtolPostMessage(SET_CLIENTHEART_PATH, &req, &rsp, false); if (g_lpHeartCb && ret) { g_lpHeartCb(rsp.msgContent.message.c_str(), rsp.timeStamp); } }, nullptr, 0, HEART_PERIOD_MS, WT_EXECUTEDEFAULT)) { SPDLOG_ERROR(TEXT("CreateTimerQueueTimer failed ({0})"), GetLastError()); return -ERR_CREATE_TIMER; } } } else { if (g_HeartTimerQueue) { if (!DeleteTimerQueue(g_HeartTimerQueue)) { SPDLOG_ERROR(TEXT("DeleteTimerQueue failed ({0})"), GetLastError()); g_HeartTimerQueue = nullptr; return -ERR_DELETE_TIMER; } g_HeartTimerQueue = nullptr; } } return ERR_SUCCESS; } int RemoteWireGuardControl(bool isStart) { int ret; ProtocolRequest req; ProtocolResponse rsp; req.msgContent.isStart = isStart; ret = ProtolPostMessage(SET_CLIENTSTART_TUNNEL, &req, &rsp, false); if (ret != ERR_SUCCESS) { return ret; } if (rsp.msgContent.errCode != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Service Response error({0}): {1}"), rsp.msgContent.errCode, rsp.msgContent.errMessage); return rsp.msgContent.errCode; } return ERR_SUCCESS; } int LocalWireGuardControl(bool isStart, bool setPrivateMode) { int ret; bool chkStatus = false; int ifInetlnetIndex, ifWireGuardIndex; // 获取 Intelnet 网络网卡 Index if ((ret = GetInternetIfIndex(&ifInetlnetIndex)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call GetInternetIfIndex error: {0}"), ret); return ret; } // 判断先前是否启动过服务 if ((ret = IsWireGuardServerRunning(GetGlobalCfgInfo()->userCfg.userName, &chkStatus)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call IsWireGuardServerInstalled error: {0}"), ret); return ret; } // 先停止以前启动的隧道服务 if (chkStatus) { if ((ret = WireGuardUnInstallServerService(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) { // 返回停止服务失败 SPDLOG_ERROR(TEXT("Call WireGuardUnInstallServerService error: {0}"), ret); return ret; } } // 移除系统所有先前ICS共享 if ((ret = RemoveAllIntelnetConnectSharing()) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call RemoveAllIntelnetConnectSharing error: {0}"), ret); return ret; } if (isStart) { // 启动服务 ret = WireGuardInstallDefaultServerService(true); if (ret != ERR_SUCCESS) { // 返回启动服务失败 SPDLOG_ERROR(TEXT("Call WireGuardInstallDefaultServerService error: {0}"), ret); return ret; } if (GetCurrentNetShareMode() == ICS_SHARE_MODE) { IP_INFO ipInfo; // 获取 WireGuard 隧道网络网卡 Index if ((ret = GetInterfaceIfIndexByName(GetGlobalCfgInfo()->userCfg.userName, &ifWireGuardIndex)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call GetInterfaceIfIndexByName error: {0}"), ret); return ret; } // 启动 WireGard 网络 ICS 服务为私有网络 if ((ret = SetNetIntelnetConnectionSharing(ifWireGuardIndex, true, true)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call SetNetIntelnetConnectionSharing error: {0}"), ret); return ret; } // 启动 Intelnet 网络 ICS 服务为公共网络 if ((ret = SetNetIntelnetConnectionSharing(ifInetlnetIndex, true, false)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call SetNetIntelnetConnectionSharing error: {0}"), ret); return ret; } // 校验 ICS 共享状态 // 检查 WireGuard 网络共享状态 if ((ret = GetNetIntelnetConnectionSharing(ifWireGuardIndex, &chkStatus)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret); return ret; } if (!chkStatus) { SPDLOG_ERROR(TEXT("WireGuard network ICS error")); return -ERR_NET_WIREGUARD_ICS; } // 检查 WireGuard 网络共享状态 if ((ret = GetNetIntelnetConnectionSharing(ifInetlnetIndex, &chkStatus)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret); return ret; } if (!chkStatus) { SPDLOG_ERROR(TEXT("Internet network ICS error")); return -ERR_NET_WIREGUARD_ICS; } GetIpV4InfoFromCIDR(GetGlobalCfgInfo()->userCfg.cliConfig.cliAddress, &ipInfo); // 检查 ICS 是否自动添加了其它非法 IP 地址 if ((ret = VerifyInterfaceIpAddr(ifWireGuardIndex, ipInfo.ip, ipInfo.netmask, 1)) != ERR_SUCCESS) { SPDLOG_WARN( TEXT("Check Windows automatic set another ip to wireguard network interface, force set to {0}/{1}"), ipInfo.ip, ipInfo.netmask); // 重设隧道 IP 地址 if ((ret = SetInterfaceIpAddressWMI(GetGlobalCfgInfo()->userCfg.userName, ipInfo.ip, ipInfo.netmask)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call SetInterfaceIpAddressWMI error: {0}"), ret); return ret; } } SPDLOG_INFO(TEXT("Net Share Service Work now on ICS mode: {0}"), GetGlobalCfgInfo()->userCfg.userName); } else if (GetCurrentNetShareMode() == NAT_SHARE_MODE) { IP_INFO ipInfo; TCHAR ipNat[MAX_IP_LEN]; GetIpV4InfoFromCIDR(GetGlobalCfgInfo()->userCfg.cliConfig.cliAddress, &ipInfo); StringCbPrintf(ipNat, MAX_IP_LEN, TEXT("%s/%d"), ipInfo.hostmax, ipInfo.prefix); // 检查 WireGuard 网络共享状态 if ((ret = SetNATRule(GetGlobalCfgInfo()->userCfg.userName, ipNat)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret); return ret; } SPDLOG_INFO(TEXT("Net Share Service Work now on NAT mode: {0}_nat --> {1}"), GetGlobalCfgInfo()->userCfg.userName, ipNat); } else { SPDLOG_ERROR(TEXT("Not support Net Share Type: {0}"), static_cast(GetCurrentNetShareMode())); return -ERR_UN_SUPPORT; } } else { if (GetCurrentNetShareMode() == NAT_SHARE_MODE) { // 检查 WireGuard 网络共享状态 if ((ret = RemoveNATRule(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call RemoveNATRule error: {0}"), ret); return ret; } } SPDLOG_INFO(TEXT("Net Share Service Stoped: {0}"), GetGlobalCfgInfo()->userCfg.userName); } return ERR_SUCCESS; } int RemoteCtrlSvrCfgUserTunnel(int vmId, const TCHAR *pCliNetwork) { const PUSER_CONFIG pUser = &GetGlobalCfgInfo()->userCfg; const PUSER_CLIENT_CONFIG pUserCfg = &pUser->cliConfig; for (int i = 0; i < pUserCfg->tolVM; i++) { if (pUserCfg->pVMConfig[i].vmId == vmId) { IP_INFO ipInfo = {}; int ret; ProtocolRequest req; ProtocolResponse rsp; req.msgContent.cliPublicKey = pUserCfg->cliPublicKey; req.msgContent.cliNetwork = pCliNetwork; GetIpV4InfoFromCIDR(pUserCfg->cliAddress, &ipInfo); req.msgContent.cliTunnelAddr = std::string(ipInfo.network) + "/" + std::to_string(ipInfo.prefix); GetGlobalCfgInfo()->curConnVmId = vmId; SPDLOG_DEBUG(TEXT("Current VMID: {0}"), vmId); // 连接到服务端控制服务 InitControlServer(pUserCfg->pVMConfig[i].scgGateWay); // 发送本地配置参数到控制服务 ret = ProtolPostMessage(SET_CLIENTCFG_PATH, &req, &rsp, false); if (ret != ERR_SUCCESS) { return ret; } if (rsp.msgContent.errCode != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Service Response error({0}): {1}"), rsp.msgContent.errCode, rsp.msgContent.errMessage); return rsp.msgContent.errCode; } // 返回成功配置本地参数 ret = SetTunnelConfigure(pUserCfg->cliPrivateKey, pUserCfg->pVMConfig[i].svrPublicKey, pUserCfg->pVMConfig[i].vmNetwork, pUserCfg->cliAddress, rsp.msgContent.svrNetwork.c_str(), pUserCfg->pVMConfig[i].scgTunnelGw); if (ret != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("SetTunnelConfigure Error: {0}"), ret); return ret; } return ERR_SUCCESS; } } return -ERR_ITEM_UNEXISTS; } int SetTunnelConfigure(const TCHAR *pCliPrivateKey, const TCHAR *pSvrPublicKey, const TCHAR *pSvrNetwork, const TCHAR *pCliNetwork, const TCHAR *pSvrTunnelAddr, const TCHAR *pSvrEndPoint) { int ret; bool isSvrStart = false; int ifInetlnetIndex; IP_INFO tunnelInfo = {}; IP_INFO svrInfo = {}; WGCLIENT_CONFIG cliCfg = {}; #pragma region if (pCliPrivateKey == nullptr || lstrlen(pCliPrivateKey) == 0) { SPDLOG_ERROR(TEXT("Input pCliPrivateKey error: {0}"), pCliPrivateKey); return -ERR_INPUT_PARAMS; } if (pSvrPublicKey == nullptr || lstrlen(pSvrPublicKey) == 0) { SPDLOG_ERROR(TEXT("Input pSvrPublicKey error: {0}"), pSvrPublicKey); return -ERR_INPUT_PARAMS; } if (pSvrNetwork == nullptr || lstrlen(pSvrNetwork) == 0) { SPDLOG_ERROR(TEXT("Input pSvrNetwork error: {0}"), pSvrNetwork); return -ERR_INPUT_PARAMS; } if (pCliNetwork == nullptr || lstrlen(pCliNetwork) == 0) { SPDLOG_ERROR(TEXT("Input pCliNetwork error: {0}"), pCliNetwork); return -ERR_INPUT_PARAMS; } if (pSvrTunnelAddr == nullptr || lstrlen(pSvrTunnelAddr) == 0) { SPDLOG_ERROR(TEXT("Input pSvrTunnelAddr error: {0}"), pSvrTunnelAddr); return -ERR_INPUT_PARAMS; } if (pSvrEndPoint == nullptr || lstrlen(pSvrEndPoint) == 0) { SPDLOG_ERROR(TEXT("Input pSvrEndPoint error: {0}"), pSvrEndPoint); return -ERR_INPUT_PARAMS; } #pragma endregion 参数检查 // 判断先前是否启动过服务 if ((ret = IsWireGuardServerRunning(GetGlobalCfgInfo()->userCfg.userName, &isSvrStart)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("IsWireGuardServerInstalled error: {0}"), ret); return ret; } // 停止先前隧道网络 if (isSvrStart) { SPDLOG_DEBUG(TEXT("WireGuardUnInstallServerService: {0}"), GetGlobalCfgInfo()->userCfg.userName); if ((ret = WireGuardUnInstallServerService(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) { // 返回停止服务失败 SPDLOG_ERROR(TEXT("WireGuardUnInstallServerService error: {0}"), ret); return ret; } } // 获取 Intelnet 网络网卡 Index if ((ret = GetInternetIfIndex(&ifInetlnetIndex)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call GetInternetIfIndex error: {0}"), ret); return ret; } if (GetCurrentNetShareMode() == ICS_SHARE_MODE) { // 检查 Internet 网络共享状态 if ((ret = GetNetIntelnetConnectionSharing(ifInetlnetIndex, &isSvrStart)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret); return ret; } // 关闭 Intelnet 网络连接共享 if (isSvrStart) { if ((ret = SetNetIntelnetConnectionSharing(ifInetlnetIndex, false, false)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Call SetNetIntelnetConnectionSharing error: {0}"), ret); return ret; } } } ret = GetIpV4InfoFromCIDR(pSvrTunnelAddr, &tunnelInfo); if (ret != ERR_SUCCESS) { return ret; } ret = GetIpV4InfoFromCIDR(pSvrNetwork, &svrInfo); if (ret != ERR_SUCCESS) { return ret; } memset(&cliCfg, 0, sizeof(WGCLIENT_CONFIG)); StringCbCopy(cliCfg.Name, 64, GetGlobalCfgInfo()->userCfg.userName); StringCbCopy(cliCfg.PrivateKey, 64, pCliPrivateKey); StringCbCopy(cliCfg.Address, 32, pCliNetwork); StringCbCopy(cliCfg.SvrPubKey, 64, pSvrPublicKey); #if USED_PORTMAP_TUNNEL StringCbCopy(cliCfg.ServerURL, 256, pSvrEndPoint); #else if (UsedSCGProxy()) { StringCbPrintf(cliCfg.ServerURL, 256, TEXT("127.0.0.1:%d"), GetGlobalCfgInfo()->scgProxy.proxyPort); } else { StringCbCopy(cliCfg.ServerURL, 256, pSvrEndPoint); } #endif StringCbPrintf(cliCfg.AllowNet, 256, TEXT("%s/%d,%s/%d"), tunnelInfo.network, tunnelInfo.prefix, svrInfo.network, svrInfo.prefix); ret = WireGuardCreateClientConfig(&cliCfg); if (ret != ERR_SUCCESS) { return ret; } return ERR_SUCCESS; } int GetUserServerConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_SERVER_CONFIG *pSvrCfg) { int ret; PUSER_CONFIG pUser = &GetGlobalCfgInfo()->userCfg; PUSER_SERVER_CONFIG pUserCfg = &pUser->svrConfig; TCHAR *pConvRet; #if USER_REAL_PLATFORM ProtocolRequest req; ProtocolResponse rsp; #else PlatformReqServerCfgParms req; PlatformRspServerCfgParams rsp; #endif if (pSvrCfg == nullptr) { SPDLOG_ERROR(TEXT("Input pSvrCfg params error")); return -ERR_INPUT_PARAMS; } if (pToken == nullptr || lstrlen(pToken) == 0) { SPDLOG_ERROR(TEXT("Input pToken params error: {0}"), pToken); return -ERR_INPUT_PARAMS; } if (pUserName && lstrlen(pUserName) > 0) { memset(pUser->userName, 0, MAX_PATH); StringCbCopy(pUser->userName, MAX_PATH, pUserName); } else { StringCbCopy(pUser->userName, MAX_PATH, TEXT("tunnel_svr")); } StringCbCopy(pUser->userToken, MAX_PATH, pToken); #if USER_REAL_PLATFORM req.msgContent.token = pToken; req.msgContent.user = pUser->userName; ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp, true); if (ret != ERR_SUCCESS) { return ret; } pUserCfg->svrListenPort = rsp.msgContent.svrListenPort; StringCbCopy(pUserCfg->svrPrivateKey, 64, rsp.msgContent.svrPrivateKey.c_str()); StringCbCopy(pUserCfg->svrAddress, MAX_IP_LEN, rsp.msgContent.svrAddress.c_str()); #else req.extVmId = pToken; ret = PlatformProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp); if (ret != ERR_SUCCESS) { return ret; } ret = strtol(rsp.code.c_str(), &pConvRet, 10); if (ret != 0 || lstrlen(pConvRet) > 0) { SPDLOG_ERROR(TEXT("Server response error code: {0}"), ret); return -ERR_HTTP_SERVER_RSP; } pUserCfg->svrListenPort = rsp.data.svrPort; StringCbCopy(pUserCfg->svrPrivateKey, 64, rsp.data.svrPriKey.c_str()); StringCbCopy(pUserCfg->svrAddress, MAX_IP_LEN, rsp.data.svrHost.c_str()); #endif *pSvrCfg = pUserCfg; return ERR_SUCCESS; } int GetUserClientConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CLIENT_CONFIG *pCliCfg) { PUSER_CONFIG pUser = &GetGlobalCfgInfo()->userCfg; PUSER_CLIENT_CONFIG pUserCfg = &pUser->cliConfig; TCHAR userPath[MAX_PATH]; int ret; TCHAR *pConvRet; #if USER_REAL_PLATFORM ProtocolRequest req; ProtocolResponse rsp; #else PlatformReqClientCfgParms req; PlatformRspClientCfgParams rsp; #endif if (pUserName == nullptr || lstrlen(pUserName) == 0) { SPDLOG_ERROR(TEXT("Input pUserName params error: {0}"), pUserName); return -ERR_INPUT_PARAMS; } if (pToken == nullptr || lstrlen(pToken) == 0) { SPDLOG_ERROR(TEXT("Input pToken params error: {0}"), pToken); return -ERR_INPUT_PARAMS; } if (pCliCfg == nullptr) { SPDLOG_ERROR(TEXT("Input pCliCfg params error")); return -ERR_INPUT_PARAMS; } StringCbPrintf(userPath, MAX_PATH, "%s\\%s", GetGlobalCfgInfo()->configDirectory, pUserName); // 如果配置目录不存在则自动创建 if (!PathFileExists(userPath)) { if (!CreateDirectory(userPath, nullptr)) { SPDLOG_ERROR(TEXT("Create user {1} directory '{0}' error."), userPath, pUserName); return -ERR_CREATE_FILE; } } memset(pUser->userName, 0, MAX_PATH); if (pUserName && lstrlen(pUserName) > 0) { StringCbCopy(pUser->userName, MAX_PATH, pUserName); } StringCbCopy(pUser->userToken, MAX_PATH, pToken); #if USER_REAL_PLATFORM req.msgContent.token = pToken; req.msgContent.user = pUserName; ret = ProtolPostMessage(GET_CLIENTCFG_PATH, &req, &rsp, true); if (ret != ERR_SUCCESS) { return ret; } StringCbCopy(pUserCfg->cliPrivateKey, 64, rsp.msgContent.cliPrivateKey.c_str()); StringCbCopy(pUserCfg->cliPublicKey, 64, rsp.msgContent.cliPublicKey.c_str()); StringCbCopy(pUserCfg->cliAddress, MAX_IP_LEN, rsp.msgContent.cliAddress.c_str()); if (!rsp.msgContent.vmConfig.empty()) { PVM_CFG pVm; unsigned int memSize = sizeof(VM_CFG) * static_cast(rsp.msgContent.vmConfig.size()); pUserCfg->pVMConfig = static_cast(CoTaskMemAlloc(memSize)); if (pUserCfg->pVMConfig == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory {0} bytes"), memSize); return -ERR_MALLOC_MEMORY; } memset(pUserCfg->pVMConfig, 0, memSize); pUserCfg->tolVM = static_cast(rsp.msgContent.vmConfig.size()); pVm = pUserCfg->pVMConfig; for (auto vm : rsp.msgContent.vmConfig) { TCHAR tmpAddr[MAX_PATH]; pVm->vmId = vm.vmId; StringCbCopy(pVm->vmName, MAX_PATH, vm.vmName.c_str()); StringCbCopy(pVm->svrPublicKey, 64, vm.svrPublicKey.c_str()); StringCbCopy(pVm->vmNetwork, MAX_IP_LEN, vm.vmNetwork.c_str()); //StringCbCopy(pVm->scgGateWay, MAX_PATH, vm.scgGateway.c_str()); StringCbPrintf(pVm->scgGateWay, MAX_PATH, TEXT("http://%s"), vm.scgGateway.c_str()); StringCbCopy(tmpAddr, MAX_PATH, vm.scgGateway.c_str()); httplib::Client cli(pVm->scgGateWay); StringCbPrintf(pVm->scgTunnelGw, MAX_PATH, TEXT("%s:%d"), cli.host().c_str(), cli.port() - 1); pVm++; } } #else req.userName = pUserName; req.token = pToken; ret = PlatformProtolPostMessage(GET_CLIENTCFG_PATH, &req, &rsp); if (ret != ERR_SUCCESS) { return ret; } ret = strtol(rsp.code.c_str(), &pConvRet, 10); if (ret != 0 || lstrlen(pConvRet) > 0) { SPDLOG_ERROR(TEXT("Server response error code: {0}"), ret); return -ERR_HTTP_SERVER_RSP; } StringCbCopy(pUserCfg->cliPrivateKey, 64, rsp.data.cliPriKey.c_str()); StringCbCopy(pUserCfg->cliPublicKey, 64, rsp.data.cliPubKey.c_str()); StringCbCopy(pUserCfg->cliAddress, MAX_IP_LEN, rsp.data.cliHost.c_str()); if (!rsp.data.vmInfoList.empty()) { PVM_CFG pVm; unsigned int memSize = sizeof(VM_CFG) * static_cast(rsp.data.vmInfoList.size()); pUserCfg->pVMConfig = static_cast(CoTaskMemAlloc(memSize)); if (pUserCfg->pVMConfig == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory {0} bytes"), memSize); return -ERR_MALLOC_MEMORY; } memset(pUserCfg->pVMConfig, 0, memSize); pUserCfg->tolVM = static_cast(rsp.data.vmInfoList.size()); pVm = pUserCfg->pVMConfig; for (auto vm : rsp.data.vmInfoList) { pVm->vmId = vm.vmId; StringCbCopy(pVm->vmName, MAX_PATH, vm.vmName.c_str()); StringCbCopy(pVm->svrPublicKey, 64, vm.svrPubKey.c_str()); StringCbCopy(pVm->vmNetwork, MAX_IP_LEN, vm.vmNetwork.c_str()); //StringCbCopy(pVm->scgGateWay, MAX_PATH, vm.scgGateway.c_str()); StringCbPrintf(pVm->scgGateWay, MAX_PATH, TEXT("http://%s:%d"), vm.scgIp.c_str(), vm.scgPort); #if USED_PORTMAP_TUNNEL StringCbPrintf(pVm->scgTunnelGw, MAX_PATH, TEXT("%s:%d"), vm.portMapIp.c_str(), vm.portMapPort); #else StringCbPrintf(pVm->scgTunnelGw, MAX_PATH, TEXT("%s:%d"), vm.scgIp.c_str(), vm.scgPort - 1); #endif pVm++; } } #endif *pCliCfg = pUserCfg; return ERR_SUCCESS; } int GetUserConfigFiles(const TCHAR *pUserName, PUSER_CFGFILE *pCfgFile, int *pItems) { PUSER_CFGFILE pCfg; FILE_LIST fileList = {nullptr, 0}; TCHAR fnPath[MAX_PATH] = {}; TCHAR cfgVal[MAX_PATH]; bool isSelected = false; if (pUserName == nullptr || lstrlen(pUserName) == 0) { SPDLOG_ERROR(TEXT("Input pUserName params error: {0}"), pUserName); return -ERR_INPUT_PARAMS; } if (pCfgFile == nullptr) { SPDLOG_ERROR(TEXT("Input pCfgFile params error")); return -ERR_INPUT_PARAMS; } if (pItems == nullptr) { SPDLOG_ERROR(TEXT("Input pItems params error")); return -ERR_INPUT_PARAMS; } GetPrivateProfileString(CFG_WIREGUARD_SECTION, CFG_WGCFG_PATH, TEXT(""), cfgVal, MAX_PATH, GetGlobalCfgInfo()->cfgPath); if (PathFileExists(cfgVal)) { isSelected = true; } StringCbPrintf(fnPath, MAX_PATH, "%s\\%s\\*.conf", GetGlobalCfgInfo()->configDirectory, pUserName); int ret = FindFile(fnPath, &fileList, false); if (ret != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Find WireGuard user {1} configure file error: {0}"), ret, pUserName); return ret; } pCfg = static_cast(CoTaskMemAlloc(sizeof(USER_CFGFILE) * fileList.nItems)); if (pCfg == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory {0} bytes"), sizeof(USER_CFGFILE) * fileList.nItems); return -ERR_SUCCESS; } memset(pCfg, 0, sizeof(USER_CFGFILE) * fileList.nItems); *pCfgFile = pCfg; *pItems = static_cast(fileList.nItems); for (unsigned int i = 0; fileList.pFilePath && i < fileList.nItems; i++) { StringCbCopy(pCfg->CfgPath, MAX_PATH, fileList.pFilePath[i].path); if (isSelected && StrCmp(pCfg->CfgPath, cfgVal) == 0) { pCfg->isCurrent = true; } else { pCfg->isCurrent = false; } pCfg++; } if (fileList.pFilePath) { HeapFree(GetProcessHeap(), 0, fileList.pFilePath); } return ERR_SUCCESS; }