diff --git a/InstallerSDK_amd64/InstallerSDK_amd64.vdproj b/InstallerSDK_amd64/InstallerSDK_amd64.vdproj index e5aec64..6f4ea70 100644 --- a/InstallerSDK_amd64/InstallerSDK_amd64.vdproj +++ b/InstallerSDK_amd64/InstallerSDK_amd64.vdproj @@ -75,6 +75,12 @@ } "Entry" { + "MsmKey" = "8:_C3B25B99ADE3C49D4C09315B7B9AF773" + "OwnerKey" = "8:_536090BAB697484B8E206852993F24BA" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_CAF1EAED19FEB8585EE0E5550C6CD814" "OwnerKey" = "8:_536090BAB697484B8E206852993F24BA" "MsmSig" = "8:_UNDEFINED" @@ -388,6 +394,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C3B25B99ADE3C49D4C09315B7B9AF773" + { + "SourcePath" = "8:CRYPT32.dll" + "TargetName" = "8:CRYPT32.dll" + "Tag" = "8:" + "Folder" = "8:_11B6E97F977B4EE4ACBB201BA1EA1604" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CAF1EAED19FEB8585EE0E5550C6CD814" { "SourcePath" = "8:VCRUNTIME140D.dll" @@ -567,7 +593,7 @@ "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:SCCSDK" "ProductCode" = "8:{0F21F61E-F559-45D3-9390-20D2563CC2F8}" - "PackageCode" = "8:{2724017F-EDD5-418B-98CD-97213E2613E4}" + "PackageCode" = "8:{08AA3750-7A2C-4493-8744-99993482EEA1}" "UpgradeCode" = "8:{30151F2E-31C5-44AC-82C4-5FCF9D54BCF3}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" diff --git a/NetTunnelApp/MainForm.cs b/NetTunnelApp/MainForm.cs index 6f991c4..f83f395 100644 --- a/NetTunnelApp/MainForm.cs +++ b/NetTunnelApp/MainForm.cs @@ -45,8 +45,8 @@ public partial class MainForm : Form var path = Environment.CurrentDirectory + "\\tunnelsdk_" + string.Format("{0:yyyyMMdd}", DateTime.Now) + ".log"; //NetTunnelLib.InitTunnelSDKLog(path, LogLevel.LOG_DEBUG); - NetTunnelLib.TunnelSDKInitEnv(Environment.CurrentDirectory, "http://xajhuang.com:9276", path, LogLevel.LOG_DEBUG, menuSetModeServer.Checked); - //NetTunnelLib.EnableSCGProxy(true, "efc.xajhuang.com", 10000); + NetTunnelLib.TunnelSDKInitEnv(Environment.CurrentDirectory, "http://xajhuang.com:9276", path, LogLevel.LOG_TRACE, menuSetModeServer.Checked); + NetTunnelLib.EnableSCGProxy(true, "efc.xajhuang.com", 10001); GetCurrentNetCard(); NetCardMenuItems menuItems = new NetCardMenuItems(_curNetCard); diff --git a/NetTunnelSDK/UserManager.cpp b/NetTunnelSDK/UserManager.cpp index 05798d0..581eb4b 100644 --- a/NetTunnelSDK/UserManager.cpp +++ b/NetTunnelSDK/UserManager.cpp @@ -233,6 +233,9 @@ int RemoteCtrlSvrCfgUserTunnel(int vmId, const TCHAR *pCliNetwork) { GetIpV4InfoFromCIDR(pUserCfg->cliAddress, &ipInfo); req.msgContent.cliTunnelAddr = ipInfo.ip; + GetGlobalCfgInfo()->curConnVmId = vmId; + SPDLOG_DEBUG(TEXT("Current VMID: {0}"), vmId); + // 连接到服务端控制服务 InitControlServer(pUserCfg->pVMConfig[i].scgGateWay); @@ -263,7 +266,6 @@ int RemoteCtrlSvrCfgUserTunnel(int vmId, const TCHAR *pCliNetwork) { return ret; } - GetGlobalCfgInfo()->curConnVmId = vmId; return ERR_SUCCESS; } } @@ -427,7 +429,7 @@ int GetUserServerConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_SE req.msgContent.token = pToken; req.msgContent.user = pUser->userName; - ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp); + ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp, true); if (ret != ERR_SUCCESS) { return ret; @@ -483,14 +485,12 @@ int GetUserClientConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CL req.msgContent.token = pToken; req.msgContent.user = pUserName; - ret = ProtolPostMessage(GET_CLIENTCFG_PATH, &req, &rsp); + ret = ProtolPostMessage(GET_CLIENTCFG_PATH, &req, &rsp, true); if (ret != ERR_SUCCESS) { return ret; } - - pUserCfg->scgCtrlAppId = rsp.msgContent.scgCtrlAppId; - pUserCfg->scgTunnelAppId = rsp.msgContent.scgTunnelAppId; + 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()); diff --git a/NetTunnelSDK/crypto/HashDigest.cpp b/NetTunnelSDK/crypto/HashDigest.cpp index ad32e34..1ecebb4 100644 --- a/NetTunnelSDK/crypto/HashDigest.cpp +++ b/NetTunnelSDK/crypto/HashDigest.cpp @@ -4,14 +4,14 @@ #include "misc.h" #include +#include #include #include #pragma comment(lib, "Bcrypt.lib") +#pragma comment(lib, "Crypt32.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, @@ -23,7 +23,7 @@ static const LPCWSTR g_BcryptHash[] = { BCRYPT_SHA512_ALGORITHM, }; -int CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]) { +int CalcFileHash(HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]) { HANDLE hFile; BYTE rgbFile[1024]; DWORD cbRead = 0; @@ -155,5 +155,139 @@ int CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]) { HeapFree(GetProcessHeap(), 0, pbHash); CloseHandle(hFile); + return ERR_SUCCESS; +} + +/** + * @brief 计算 HMAC HASH 值 + * @param[in] type Hash 类型 @see HASH_TYPE + * @param[in] pHashData 需要计算 Hash 值的数据 + * @param[in] inSize 需要计算 Hash 值的数据大小(字节数) + * @param[in] pKey HMAC Hash 秘钥 + * @param[in] keySize HMAC Hash 秘钥大小(字节数) + * @param[out] outHash 计算结果 + * @param[in] outBase64 是否以 BASE64 字符串输出 + * @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 成功 + */ +int CalcHmacHash(HASH_TYPE type, + PUCHAR pHashData, + int inSize, + PUCHAR pKey, + int keySize, + TCHAR outHash[], + bool outBase64) { + BCRYPT_ALG_HANDLE hAlg = nullptr; + BCRYPT_HASH_HANDLE hHash = nullptr; + NTSTATUS status; + DWORD cbData = 0, cbHash = 0, cbHashObject = 0; + PBYTE pbHashObject; + PBYTE pbHash; + + //open an algorithm handle + if (NT_FAILED( + status = BCryptOpenAlgorithmProvider(&hAlg, g_BcryptHash[type], nullptr, BCRYPT_ALG_HANDLE_HMAC_FLAG))) { + SPDLOG_ERROR(TEXT("Error {0} returned by BCryptOpenAlgorithmProvider"), status); + 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(&cbHashObject), + sizeof(DWORD), + &cbData, + 0))) { + SPDLOG_ERROR(TEXT("Error {0} returned by BCryptGetProperty"), status); + BCryptCloseAlgorithmProvider(hAlg, 0); + return -ERR_BCRYPT_GETPROPERTY; + } + + //allocate the hash object on the heap + pbHashObject = static_cast(HeapAlloc(GetProcessHeap(), 0, cbHashObject)); + if (nullptr == pbHashObject) { + SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), cbHashObject); + BCryptCloseAlgorithmProvider(hAlg, 0); + return -ERR_MALLOC_MEMORY; + } + + //calculate the length of the hash + if (NT_FAILED(status = BCryptGetProperty(hAlg, + BCRYPT_HASH_LENGTH, + reinterpret_cast(&cbHash), + sizeof(DWORD), + &cbData, + 0))) { + SPDLOG_ERROR(TEXT("Error {0} returned by BCryptGetProperty"), status); + BCryptCloseAlgorithmProvider(hAlg, 0); + HeapFree(GetProcessHeap(), 0, pbHashObject); + return -ERR_BCRYPT_GETPROPERTY; + } + + //allocate the hash buffer on the heap + pbHash = static_cast(HeapAlloc(GetProcessHeap(), 0, cbHash)); + if (nullptr == pbHash) { + SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), cbHash); + BCryptCloseAlgorithmProvider(hAlg, 0); + HeapFree(GetProcessHeap(), 0, pbHashObject); + return -ERR_MALLOC_MEMORY; + } + + //create a hash + if (NT_FAILED(status = BCryptCreateHash(hAlg, &hHash, pbHashObject, cbHashObject, pKey, keySize, 0))) { + SPDLOG_ERROR(TEXT("Error {0} returned by BCryptCreateHash"), status); + BCryptCloseAlgorithmProvider(hAlg, 0); + HeapFree(GetProcessHeap(), 0, pbHashObject); + HeapFree(GetProcessHeap(), 0, pbHash); + return -ERR_BCRYPT_CREATEHASH; + } + + //hash some data + if (NT_FAILED(status = BCryptHashData(hHash, pHashData, inSize, 0))) { + SPDLOG_ERROR(TEXT("Error {0} returned by BCryptHashData"), status); + 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); + BCryptCloseAlgorithmProvider(hAlg, 0); + BCryptDestroyHash(hHash); + HeapFree(GetProcessHeap(), 0, pbHashObject); + HeapFree(GetProcessHeap(), 0, pbHash); + return -ERR_BCRYPT_FINISHHASH; + } + + if (outBase64) { + DWORD len; + if (!CryptBinaryToString(pbHash, cbHash, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, outHash, &len)) { + SPDLOG_ERROR(TEXT("Error {0} returned by BCryptFinishHash"), status); + BCryptCloseAlgorithmProvider(hAlg, 0); + BCryptDestroyHash(hHash); + HeapFree(GetProcessHeap(), 0, pbHashObject); + HeapFree(GetProcessHeap(), 0, pbHash); + return -ERR_BCRYPT_FINISHHASH; + } + } else { + binToHexString(outHash, pbHash, cbHash); + } + + BCryptCloseAlgorithmProvider(hAlg, 0); + BCryptDestroyHash(hHash); + HeapFree(GetProcessHeap(), 0, pbHashObject); + HeapFree(GetProcessHeap(), 0, pbHash); + return ERR_SUCCESS; } \ No newline at end of file diff --git a/NetTunnelSDK/include/framework.h b/NetTunnelSDK/include/framework.h index 80cbbc9..612dab5 100644 --- a/NetTunnelSDK/include/framework.h +++ b/NetTunnelSDK/include/framework.h @@ -1,5 +1,5 @@ #pragma once -#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 +#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 // Windows 头文件 #include diff --git a/NetTunnelSDK/include/globalcfg.h b/NetTunnelSDK/include/globalcfg.h index 0f3ce52..0f3598c 100644 --- a/NetTunnelSDK/include/globalcfg.h +++ b/NetTunnelSDK/include/globalcfg.h @@ -68,6 +68,8 @@ typedef struct { USER_CONFIG userCfg; ///< 用户配置项 SCG_PROXY_INFO scgProxy; ///< SCG UDP 代理信息 int curConnVmId; ///< 当前连接的VM + TCHAR clientId[MAX_PATH]; ///< 客户端验证签名 ID + TCHAR clientSecret[MAX_PATH]; ///< 客户端验证签名秘钥 } SDK_CONFIG, *PSDK_CONFIG; #ifdef __cplusplus // If used by C++ code, diff --git a/NetTunnelSDK/include/httplib.h b/NetTunnelSDK/include/httplib.h index bfa8b56..60af391 100644 --- a/NetTunnelSDK/include/httplib.h +++ b/NetTunnelSDK/include/httplib.h @@ -2174,7 +2174,7 @@ inline std::string from_i_to_hex(size_t n) { static const auto charset = "0123456789abcdef"; std::string ret; do { - ret = charset[n & 15] + ret; + ret = charset[n & 15] + ret; n >>= 4; } while (n > 0); return ret; @@ -2224,7 +2224,7 @@ inline std::string base64_encode(const std::string &in) { auto valb = -6; for (auto c : in) { - val = (val << 8) + static_cast(c); + val = (val << 8) + static_cast(c); valb += 8; while (valb >= 0) { out.push_back(lookup[(val >> valb) & 0x3F]); @@ -4206,7 +4206,7 @@ inline bool write_content_chunked(Stream &strm, data_sink.write = [&](const char *d, size_t l) -> bool { if (ok) { - data_available = l > 0; + data_available = l > 0; offset += l; std::string payload; @@ -4311,8 +4311,8 @@ inline bool redirect(T &cli, const std::string &path, const std::string &location, Error &error) { - Request new_req = req; - new_req.path = path; + Request new_req = req; + new_req.path = path; new_req.redirect_count_ -= 1; if (res.status == 303 && (req.method != "GET" && req.method != "HEAD")) { @@ -4736,7 +4736,7 @@ inline bool is_multipart_boundary_chars_valid(const std::string &boundary) { template inline std::string serialize_multipart_formdata_item_begin(const T &item, const std::string &boundary) { - std::string body = "--" + boundary + "\r\n"; + std::string body = "--" + boundary + "\r\n"; body += "Content-Disposition: form-data; name=\"" + item.name + "\""; if (!item.filename.empty()) { body += "; filename=\"" + item.filename + "\""; @@ -4800,7 +4800,7 @@ inline std::pair get_range_offset_and_length(const Request &req, } inline std::string make_content_range_header_field(size_t offset, size_t length, size_t content_length) { - std::string field = "bytes "; + std::string field = "bytes "; field += std::to_string(offset); field += "-"; field += std::to_string(offset + length - 1); @@ -5010,8 +5010,8 @@ inline void cf_object_ptr_deleter(CFTypeRef obj) { } inline bool retrieve_certs_from_keychain(CFObjectPtr &certs) { - CFStringRef keys[] = {kSecClass, kSecMatchLimit, kSecReturnRef}; - CFTypeRef values[] = {kSecClassCertificate, kSecMatchLimitAll, kCFBooleanTrue}; + CFStringRef keys[] = {kSecClass, kSecMatchLimit, kSecReturnRef}; + CFTypeRef values[] = {kSecClassCertificate, kSecMatchLimitAll, kCFBooleanTrue}; CFObjectPtr query(CFDictionaryCreate(nullptr, reinterpret_cast(keys), @@ -5076,7 +5076,7 @@ inline bool add_certs_to_x509_store(CFArrayRef certs, X509_STORE *store) { } inline bool load_system_certs_on_macos(X509_STORE *store) { - auto result = false; + auto result = false; CFObjectPtr certs(nullptr, cf_object_ptr_deleter); if (retrieve_certs_from_keychain(certs) && certs) { result = add_certs_to_x509_store(certs.get(), store); @@ -5276,7 +5276,7 @@ inline void hosted_at(const std::string &hostname, std::vector &add inline std::string append_query_params(const std::string &path, const Params ¶ms) { std::string path_with_query = path; const static std::regex re("[^?]+\\?.*"); - auto delm = std::regex_match(path, re) ? '&' : '?'; + auto delm = std::regex_match(path, re) ? '&' : '?'; path_with_query += delm + detail::params_to_query_str(params); return path_with_query; } @@ -5511,7 +5511,7 @@ inline ssize_t SocketStream::read(char *ptr, size_t size) { #ifdef _WIN32 size = (std::min)(size, static_cast((std::numeric_limits::max)())); #else - size = (std::min)(size, static_cast((std::numeric_limits::max)())); + size = (std::min)(size, static_cast((std::numeric_limits::max)())); #endif if (read_buff_off_ < read_buff_content_size_) { @@ -7088,7 +7088,7 @@ inline bool ClientImpl::send_(Request &req, Response &res, Error &error) { assert(socket_requests_are_from_thread_ == std::this_thread::get_id()); } socket_requests_in_flight_ += 1; - socket_requests_are_from_thread_ = std::this_thread::get_id(); + socket_requests_are_from_thread_ = std::this_thread::get_id(); } for (const auto &header : default_headers_) { @@ -7178,7 +7178,7 @@ inline bool ClientImpl::handle_request(Stream &strm, Request &req, Response &res if (!username.empty() && !password.empty()) { std::map auth; if (detail::parse_www_authenticate(res, auth, is_proxy)) { - Request new_req = req; + Request new_req = req; new_req.authorization_count_ += 1; new_req.headers.erase(is_proxy ? "Proxy-Authorization" : "Authorization"); new_req.headers.insert(detail::make_digest_authentication_header(req, @@ -7653,8 +7653,8 @@ inline ContentProviderWithoutLength ClientImpl::get_multipart_content_provider( } else if (cur_item < provider_items.size()) { if (!cur_start) { const auto &begin = detail::serialize_multipart_formdata_item_begin(provider_items[cur_item], boundary); - offset += begin.size(); - cur_start = offset; + offset += begin.size(); + cur_start = offset; sink.os << begin; } diff --git a/NetTunnelSDK/include/network.h b/NetTunnelSDK/include/network.h index c980205..1d10d5e 100644 --- a/NetTunnelSDK/include/network.h +++ b/NetTunnelSDK/include/network.h @@ -75,19 +75,6 @@ int GetInterfaceGUIDByName(const TCHAR *pInterfaceName, GUID *pGuid); int WaitNetAdapterConnected(const TCHAR *pInterfaceName, int timeOutOfMs); -/** - * @brief 判断当前网络适配器是否拥有 Internet 连接 - * @param[in] ifIndex 网卡适配器索引 - * @param[in] pRet 连接属性 - * - TRUE 网卡适配器具有 Internet 连接 - * - FALSE 网卡适配器无 Internet 连接 - * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERR_INPUT_PARAMS 输入参数错误 - * - -ERR_GET_IPFOWARDTBL 获取防火墙信息失败 - * - ERR_SUCCESS 成功 - */ -int IsInternetConnectAdapter(int ifIndex, bool *pRet); - /** * @brief 获取网卡 NetworkCategory 是否设置为 Private 模式 * @param[in] pInterfaceName 网卡名称 diff --git a/NetTunnelSDK/include/protocol.h b/NetTunnelSDK/include/protocol.h index 0748630..2b81e15 100644 --- a/NetTunnelSDK/include/protocol.h +++ b/NetTunnelSDK/include/protocol.h @@ -131,7 +131,7 @@ template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, ProtocolResponse *pRsp, - bool platformServer = true); + bool platformServer); extern template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, diff --git a/NetTunnelSDK/include/sccsdk.h b/NetTunnelSDK/include/sccsdk.h index f6b3dfd..fb0af36 100644 --- a/NetTunnelSDK/include/sccsdk.h +++ b/NetTunnelSDK/include/sccsdk.h @@ -154,6 +154,34 @@ SCCSDK_API int __cdecl GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts); */ SCCSDK_API int __cdecl GetInternetIfIndex(int *pIfIndex); +/** + * @brief 判断当前网络适配器是否拥有 Internet 连接 + * @param[in] ifIndex 网卡适配器索引 + * @param[in] pRet 连接属性 + * - TRUE 网卡适配器具有 Internet 连接 + * - FALSE 网卡适配器无 Internet 连接 + * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_GET_IPFOWARDTBL 获取防火墙信息失败 + * - ERR_SUCCESS 成功 + */ +SCCSDK_API int __cdecl IsInternetConnectAdapter(int ifIndex, bool *pRet); + +/** + * @brief 打开平台接口签名验证功能 + * @param pClientId 客户端 ID + * @param pClientSecret 客户端秘钥 + * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - ERR_SUCCESS 成功 + */ +SCCSDK_API int __cdecl EnableVerifySignature(const TCHAR *pClientId, const TCHAR *pClientSecret); + +/** + * @brief 关闭平台接口签名验证功能 + */ +SCCSDK_API void __cdecl DisableVerifySignature(); + /** * @brief 云电脑服务端创建控制服务 * @param pSvr 服务端配置信息 @@ -196,6 +224,14 @@ SCCSDK_API int __cdecl GetUserClientConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CLIENT_CONFIG *pCliCfg); +/** + * @brief 停止云电脑服务端服务 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERROR_TIMEOUT 等待超时 + * - ERR_SUCCESS 成功 + */ +SCCSDK_API int __cdecl StopControlService(); + /** * @brief 连接远程控制服务配置隧道参数 * @param[in] vmId 需要连接的虚拟机ID编号 diff --git a/NetTunnelSDK/include/tunnel.h b/NetTunnelSDK/include/tunnel.h index 6cb02b6..84ae5ef 100644 --- a/NetTunnelSDK/include/tunnel.h +++ b/NetTunnelSDK/include/tunnel.h @@ -1,6 +1,11 @@ #pragma once #include "sccsdk.h" +typedef enum { + WG_TUNNEL_SCG_ID = 3, + WG_CTRL_SCG_ID = 4 +} SCG_SVR_ID; + typedef enum { CHK_SYSTEM_INIT, CHK_WIREGUARD_CONFIG, @@ -172,8 +177,29 @@ int IsWireGuardServerInstalled(bool *pIsInstalled); * - -ERR_BCRYPT_FINISHHASH 计算 Hash 结果失败 * - ERR_SUCCESS 成功 */ - int CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]); +int CalcFileHash(HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]); +/** + * @brief 计算 HMAC HASH 值 + * @param[in] type Hash 类型 @see HASH_TYPE + * @param[in] pHashData 需要计算 Hash 值的数据 + * @param[in] inSize 需要计算 Hash 值的数据大小(字节数) + * @param[in] pKey HMAC Hash 秘钥 + * @param[in] keySize HMAC Hash 秘钥大小(字节数) + * @param[out] outHash 计算结果 + * @param[in] outBase64 是否以 BASE64 字符串输出 + * @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 成功 + */ +int CalcHmacHash(HASH_TYPE type, PUCHAR pHashData, int inSize, PUCHAR pKey, int keySize, TCHAR outHash[], bool outBase64); #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/NetTunnelSDK/include/user.h b/NetTunnelSDK/include/user.h index f1b556e..972afe8 100644 --- a/NetTunnelSDK/include/user.h +++ b/NetTunnelSDK/include/user.h @@ -22,14 +22,6 @@ extern "C" { */ void ConnectServerControlService(const TCHAR *pUserSvrUrl); -/** - * @brief 停止云电脑服务端服务 - * @return 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERROR_TIMEOUT 等待超时 - * - ERR_SUCCESS 成功 - */ -int StopControlService(); - /** * @brief 设置本地 WireGuard 隧道配置 * @param[in] pCliPrivateKey 隧道私钥 diff --git a/NetTunnelSDK/network/ProxyService.cpp b/NetTunnelSDK/network/ProxyService.cpp index 990aaf5..f8efa37 100644 --- a/NetTunnelSDK/network/ProxyService.cpp +++ b/NetTunnelSDK/network/ProxyService.cpp @@ -8,25 +8,10 @@ #include #include +#include #define SCG_UDP_HEAD_SIZE (11) -typedef struct { - bool isRunning; - HANDLE proxyThread; - HANDLE proxyHandle; - bool isExitSvr; -} UDP_PROXY_CTX, *PUDP_PROXY_CTX; - -typedef struct { - TCHAR streamFilter[1024]; - TCHAR targetIp[MAX_IP_LEN]; - UINT16 targetPort; - int vmId; - int svrId; - UDP_PROXY_CTX udpCtx; -} PROXY_INFO, *PPROXY_INFO; - void StopUDPProxyServer() { const PSCG_PROXY_INFO pProxy = &GetGlobalCfgInfo()->scgProxy; pProxy->exitNow = true; @@ -90,6 +75,13 @@ static DWORD UDPProxvRemoteThread(LPVOID lpParameter) { pProxy->udpProxySock, ipAddr, ntohs(pPeerSock->sin_port)); + } else { + SPDLOG_ERROR(TEXT(">>> Scoket In {1} Recv {0} bytes from {2}:{3} error: {4}"), + iRecvBytes, + pProxy->scgGwSock, + ipAddr, + ntohs(remoteWgAddr.sin_port), + WSAGetLastError()); } Sleep(100); @@ -98,34 +90,31 @@ static DWORD UDPProxvRemoteThread(LPVOID lpParameter) { } static DWORD UDPProxyRecvThread(LPVOID lpParameter) { - bool isRemoteInit = false; - sockaddr_in localWgAddr {}; - sockaddr_in scgAddr {}; - unsigned char recvBuf[1500 + SCG_UDP_HEAD_SIZE]; - const PSCG_PROXY_INFO pProxy = &GetGlobalCfgInfo()->scgProxy; - unsigned char vmid[4]; - const unsigned int id = htonl(GetGlobalCfgInfo()->curConnVmId); - const auto svrId = static_cast(GetGlobalCfgInfo()->userCfg.cliConfig.scgTunnelAppId); - char *pRecBuf = reinterpret_cast(&recvBuf[SCG_UDP_HEAD_SIZE]); + bool isRemoteInit = false; + sockaddr_in localWgAddr {}; + sockaddr_in scgAddr {}; + unsigned char recvBuf[1500 + SCG_UDP_HEAD_SIZE]; + std::array arr; + const PSCG_PROXY_INFO pProxy = &GetGlobalCfgInfo()->scgProxy; + const auto svrId = static_cast(GetGlobalCfgInfo()->userCfg.cliConfig.scgTunnelAppId); + char *pRecBuf = reinterpret_cast(&recvBuf[SCG_UDP_HEAD_SIZE]); scgAddr.sin_family = AF_INET; scgAddr.sin_port = htons(pProxy->scgGwPort); InetPton(AF_INET, pProxy->scgIpAddr, &scgAddr.sin_addr.s_addr); - memcpy(vmid, &id, 4); - // 构建 SCG UDP 包头 - recvBuf[0] = 0x01; // VERSION - recvBuf[1] = 0x09; // Length - recvBuf[2] = 0xF0; // ++++++ INFO[0] TYPE - recvBuf[3] = 0x04; // INFO[0] LENGTH - recvBuf[4] = vmid[0]; // INFO[0] VMID[0] - recvBuf[5] = vmid[1]; // INFO[0] VMID[1] - recvBuf[6] = vmid[2]; // INFO[0] VMID[2] - recvBuf[7] = vmid[3]; // INFO[0] VMID[3] - recvBuf[8] = 0xF1; // INFO[1] TYPE - recvBuf[9] = 0x01; // INFO[1] LENGTH - recvBuf[10] = svrId; // ------ INFO[1] SCG Service ID + recvBuf[0] = 0x01; // VERSION + recvBuf[1] = 0x09; // Length + recvBuf[2] = 0xF0; // ++++++ INFO[0] TYPE + recvBuf[3] = 0x04; // INFO[0] LENGTH + recvBuf[4] = 0; // INFO[0] VMID[0] + recvBuf[5] = 0; // INFO[0] VMID[1] + recvBuf[6] = 0; // INFO[0] VMID[2] + recvBuf[7] = 0; // INFO[0] VMID[3] + recvBuf[8] = 0xF1; // INFO[1] TYPE + recvBuf[9] = 0x01; // INFO[1] LENGTH + recvBuf[10] = svrId; // ------ INFO[1] SCG Service ID pProxy->exitNow = false; while (!pProxy->exitNow) { @@ -155,7 +144,10 @@ static DWORD UDPProxyRecvThread(LPVOID lpParameter) { } if (iRecvBytes != SOCKET_ERROR) { - int sendBytes; + int sendBytes; + const unsigned int id = htonl(GetGlobalCfgInfo()->curConnVmId); + unsigned char vmid[4]; + memcpy(vmid, &id, 4); if (!isRemoteInit) { HANDLE handle; @@ -179,9 +171,24 @@ static DWORD UDPProxyRecvThread(LPVOID lpParameter) { pProxy->hProxySCGThread = handle; } + recvBuf[4] = vmid[0]; // INFO[0] VMID[0] + recvBuf[5] = vmid[1]; // INFO[0] VMID[1] + recvBuf[6] = vmid[2]; // INFO[0] VMID[2] + recvBuf[7] = vmid[3]; // INFO[0] VMID[3] + // 增加SCG包头数据长度 iRecvBytes += 11; - sendBytes = sendto(pProxy->scgGwSock, + + if (GetGlobalCfgInfo()->logLevel == spdlog::level::trace) { + const auto start = std::begin(recvBuf); + std::copy_n(start, iRecvBytes, std::begin(arr)); + SPDLOG_TRACE(TEXT("UDP Proxy SCG({1}/0x{2:X}) Payload: {0:Xa}"), + spdlog::to_hex(start, start + iRecvBytes, 16), + svrId, + id); + } + + sendBytes = sendto(pProxy->scgGwSock, reinterpret_cast(recvBuf), iRecvBytes, 0, diff --git a/NetTunnelSDK/network/network.cpp b/NetTunnelSDK/network/network.cpp index 1aec87d..c564d6c 100644 --- a/NetTunnelSDK/network/network.cpp +++ b/NetTunnelSDK/network/network.cpp @@ -161,7 +161,26 @@ int GetInterfaceNameByGUID(const TCHAR *pGUID, TCHAR ifName[MAX_NETCARD_NAME]) { reinterpret_cast(&pNSM)); if (hr != S_OK || pNSM == nullptr) { - SPDLOG_ERROR(TEXT("CoCreateInstance NetSharingManager failed: {0}."), hr); + CoInitialize(nullptr); + CoInitializeSecurity(nullptr, + -1, + nullptr, + nullptr, + RPC_C_AUTHN_LEVEL_PKT, + RPC_C_IMP_LEVEL_IMPERSONATE, + nullptr, + EOAC_NONE, + nullptr); + + hr = ::CoCreateInstance(CLSID_NetSharingManager, + nullptr, + CLSCTX_ALL, + IID_INetSharingManager, + reinterpret_cast(&pNSM)); + } + + if (hr != S_OK || pNSM == nullptr) { + SPDLOG_ERROR(TEXT("CoCreateInstance NetSharingManager failed: {0}"), hr); return -ERR_CREATE_COMMOBJECT; } diff --git a/NetTunnelSDK/protocol/protocol.cpp b/NetTunnelSDK/protocol/protocol.cpp index 9a1c71b..2ab7195 100644 --- a/NetTunnelSDK/protocol/protocol.cpp +++ b/NetTunnelSDK/protocol/protocol.cpp @@ -8,6 +8,7 @@ #include "usrerr.h" #include +#include #define HTTP_JSON_CONTENT TEXT("application/json") @@ -21,12 +22,15 @@ int InitControlServer(const TCHAR *pUserSvrUrl) { g_tunnelHttpCtx = nullptr; } - if (GetGlobalCfgInfo()->scgProxy.scgGwPort > 0) { + if (UsedSCGProxy()) { TCHAR scgProxyUrl[MAX_PATH]; StringCbPrintf(scgProxyUrl, MAX_PATH, TEXT("http://127.0.0.1:%d"), GetGlobalCfgInfo()->scgProxy.scgGwPort); - g_tunnelHttpCtx = new httplib::Client(pUserSvrUrl); + + SPDLOG_DEBUG(TEXT("Control Server Used Proxy: {0} --> {1}"), pUserSvrUrl, scgProxyUrl); + g_tunnelHttpCtx = new httplib::Client(scgProxyUrl); } else { g_tunnelHttpCtx = new httplib::Client(pUserSvrUrl); + SPDLOG_DEBUG(TEXT("Control Server Unused Proxy: {0}"), pUserSvrUrl); } if (g_tunnelHttpCtx) { @@ -59,6 +63,12 @@ int InitControlServer(const TCHAR *pUserSvrUrl) { scgProxy[6] = vmid[2]; scgProxy[7] = vmid[3]; + if (GetGlobalCfgInfo()->logLevel == spdlog::level::trace) { + std::array arr; + std::copy(std::begin(scgProxy), std::end(scgProxy), std::begin(arr)); + SPDLOG_DEBUG(TEXT("TCP Proxy SCG Payload: {0:Xa}"), spdlog::to_hex(arr)); + } + ret = send(sock, reinterpret_cast(p), sizeof(scgProxy), 0); while (ret < static_cast(sizeof(scgProxy))) { @@ -66,7 +76,10 @@ int InitControlServer(const TCHAR *pUserSvrUrl) { ret += send(sock, reinterpret_cast(p), sizeof(scgProxy), 0); } - SPDLOG_DEBUG(TEXT("Service Connected To SCG Server: {0}"), sock); + SPDLOG_DEBUG(TEXT("Service Connected To SCG Server({1}/{2}): {0}"), + sock, + GetGlobalCfgInfo()->curConnVmId, + svrId); } }); } @@ -139,7 +152,35 @@ int ProtolPostMessage(const TCHAR *pUrlPath, } if (platformServer) { - res = g_httpCtx->Post(pUrlPath, pJson, HTTP_JSON_CONTENT); + std::string timestamp = std::to_string(time(nullptr)) + "000"; + TCHAR hashValeu[MAX_PATH] = {0}; + TCHAR hashBuf[1024] = {}; + + StringCbPrintf(hashBuf, + 1024, + TEXT("%s|%s|%s|%s"), + GetGlobalCfgInfo()->clientId, + GetGlobalCfgInfo()->clientSecret, + timestamp.c_str(), + pJson); + + if (lstrlen(GetGlobalCfgInfo()->clientSecret) > 0 && + CalcHmacHash(HASH_SHA256, + reinterpret_cast(hashBuf), + lstrlen(hashBuf), + reinterpret_cast(GetGlobalCfgInfo()->clientSecret), + lstrlen(GetGlobalCfgInfo()->clientSecret), + hashValeu, + true) == ERR_SUCCESS) { + const httplib::Headers headers = { + {"gzs-client-id", GetGlobalCfgInfo()->clientId}, + {"gzs-sign", hashValeu }, + {"gzs-timestamp", timestamp }, + }; + res = g_httpCtx->Post(pUrlPath, headers, pJson, HTTP_JSON_CONTENT); + } else { + res = g_httpCtx->Post(pUrlPath, pJson, HTTP_JSON_CONTENT); + } } else { if (g_tunnelHttpCtx == nullptr) { free(pJson); @@ -178,16 +219,6 @@ int ProtolPostMessage(const TCHAR *pUrlPath, return ERR_SUCCESS; } -int ProtoGetUserConfigure(const TCHAR *pUser, const TCHAR *pToken) { - int ret; - ProtocolRequest req; - ProtocolResponse rsp; - - ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp); - - return ret; -} - template int ProtolPostMessage(const TCHAR *pUrlPath, ProtocolRequest *pReq, ProtocolResponse *pRsp, diff --git a/NetTunnelSDK/sdk/sccsdk.h b/NetTunnelSDK/sdk/sccsdk.h index 77bb976..7fb51e4 100644 --- a/NetTunnelSDK/sdk/sccsdk.h +++ b/NetTunnelSDK/sdk/sccsdk.h @@ -154,6 +154,34 @@ SCCSDK_API int __cdecl GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts); */ SCCSDK_API int __cdecl GetInternetIfIndex(int *pIfIndex); +/** + * @brief жϵǰǷӵ Internet + * @param[in] ifIndex + * @param[in] pRet + * - TRUE Internet + * - FALSE Internet + * @return ִн 0: ɹ С0 ʧ @see USER_ERRNO + * - -ERR_INPUT_PARAMS + * - -ERR_GET_IPFOWARDTBL ȡǽϢʧ + * - ERR_SUCCESS ɹ + */ +SCCSDK_API int __cdecl IsInternetConnectAdapter(int ifIndex, bool *pRet); + +/** + * @brief ƽ̨ӿǩ֤ + * @param pClientId ͻ ID + * @param pClientSecret ͻԿ + * @return ִн 0: ɹ С0 ʧ @see USER_ERRNO + * - -ERR_INPUT_PARAMS + * - ERR_SUCCESS ɹ + */ +SCCSDK_API int __cdecl EnableVerifySignature(const CHAR *pClientId, const CHAR *pClientSecret); + +/** + * @brief رƽ̨ӿǩ֤ + */ +SCCSDK_API void __cdecl DisableVerifySignature(); + /** * @brief ƵԷ˴Ʒ * @param pSvr Ϣ @@ -196,6 +224,14 @@ SCCSDK_API int __cdecl GetUserClientConfigure(const CHAR *pUserName, const CHAR *pToken, PUSER_CLIENT_CONFIG *pCliCfg); +/** + * @brief ֹͣƵԷ˷ + * @return 0: ɹ С0 ʧ @see USER_ERRNO + * - -ERROR_TIMEOUT ȴʱ + * - ERR_SUCCESS ɹ + */ +SCCSDK_API int __cdecl StopControlService(); + /** * @brief Զ̿Ʒ * @param[in] vmId ҪӵID diff --git a/NetTunnelSDK/tunnel/tunnel.cpp b/NetTunnelSDK/tunnel/tunnel.cpp index d9e3236..0908f05 100644 --- a/NetTunnelSDK/tunnel/tunnel.cpp +++ b/NetTunnelSDK/tunnel/tunnel.cpp @@ -181,6 +181,30 @@ void TunnelSDKUnInit() { WSACleanup(); } +void DisableVerifySignature() { + memset(g_globalConfig.clientId, 0, MAX_PATH); + memset(g_globalConfig.clientSecret, 0, MAX_PATH); +} + +int EnableVerifySignature(const TCHAR *pClientId, const TCHAR *pClientSecret) { + if (pClientId == nullptr || lstrlen(pClientId) == 0 || lstrlen(pClientId) >= MAX_PATH) { + SPDLOG_ERROR(TEXT("Input pClientId params error: {0}"), pClientId); + return -ERR_INPUT_PARAMS; + } + + if (pClientSecret == nullptr || lstrlen(pClientSecret) == 0 || lstrlen(pClientSecret) >= MAX_PATH) { + SPDLOG_ERROR(TEXT("Input pClientSecret params error: {0}"), pClientSecret); + return -ERR_INPUT_PARAMS; + } + + DisableVerifySignature(); + + StringCbCopy(g_globalConfig.clientId, MAX_PATH, pClientId); + StringCbCopy(g_globalConfig.clientSecret, MAX_PATH, pClientSecret); + + return ERR_SUCCESS; +} + int EnableSCGProxy(bool isEnable, const TCHAR *pSCGIpAddr, int scgPort) { if (pSCGIpAddr == nullptr || lstrlen(pSCGIpAddr) == 0 || lstrlen(pSCGIpAddr) >= MAX_IP_LEN) { @@ -197,6 +221,9 @@ int EnableSCGProxy(bool isEnable, const TCHAR *pSCGIpAddr, int scgPort) { return ret; } + g_globalConfig.userCfg.cliConfig.scgCtrlAppId = WG_CTRL_SCG_ID; + g_globalConfig.userCfg.cliConfig.scgTunnelAppId = WG_TUNNEL_SCG_ID; + StringCbCopy(g_globalConfig.scgProxy.scgIpAddr, MAX_IP_LEN, ipInfo.hostip); g_globalConfig.scgProxy.scgGwPort = static_cast(scgPort); CreateUDPProxyServer(); diff --git a/NetTunnelSDKTestApp/HmacSHA256.cpp b/NetTunnelSDKTestApp/HmacSHA256.cpp new file mode 100644 index 0000000..4a5f898 --- /dev/null +++ b/NetTunnelSDKTestApp/HmacSHA256.cpp @@ -0,0 +1,157 @@ +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (C) Microsoft. All rights reserved. +/*++ + +Abstract: + + Sample program for SHA 256 hashing using CNG + +--*/ + +#include +#include +#include + +//#pragma comment(lib, "Ncrypt.lib") + +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) + + +static const BYTE rgbMsg[] = +{ + 0x61, 0x62, 0x63 +}; + + +void __cdecl hmac_sha256() +{ + + BCRYPT_ALG_HANDLE hAlg = NULL; + BCRYPT_HASH_HANDLE hHash = NULL; + NTSTATUS status = STATUS_UNSUCCESSFUL; + DWORD cbData = 0, + cbHash = 0, + cbHashObject = 0; + PBYTE pbHashObject = NULL; + PBYTE pbHash = NULL; + + //open an algorithm handle + if(!NT_SUCCESS(status = BCryptOpenAlgorithmProvider( + &hAlg, + BCRYPT_SHA256_ALGORITHM, + NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG))) + { + wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status); + goto Cleanup; + } + + //calculate the size of the buffer to hold the hash object + if(!NT_SUCCESS(status = BCryptGetProperty( + hAlg, + BCRYPT_OBJECT_LENGTH, + (PBYTE)&cbHashObject, + sizeof(DWORD), + &cbData, + 0))) + { + wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status); + goto Cleanup; + } + + //allocate the hash object on the heap + pbHashObject = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbHashObject); + if(NULL == pbHashObject) + { + wprintf(L"**** memory allocation failed\n"); + goto Cleanup; + } + + //calculate the length of the hash + if(!NT_SUCCESS(status = BCryptGetProperty( + hAlg, + BCRYPT_HASH_LENGTH, + (PBYTE)&cbHash, + sizeof(DWORD), + &cbData, + 0))) + { + wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status); + goto Cleanup; + } + + //allocate the hash buffer on the heap + pbHash = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbHash); + if(NULL == pbHash) + { + wprintf(L"**** memory allocation failed\n"); + goto Cleanup; + } + + //create a hash + if(!NT_SUCCESS(status = BCryptCreateHash( + hAlg, + &hHash, + pbHashObject, + cbHashObject, + NULL, + 0, + 0))) + { + wprintf(L"**** Error 0x%x returned by BCryptCreateHash\n", status); + goto Cleanup; + } + + + //hash some data + if(!NT_SUCCESS(status = BCryptHashData( + hHash, + (PBYTE)rgbMsg, + sizeof(rgbMsg), + 0))) + { + wprintf(L"**** Error 0x%x returned by BCryptHashData\n", status); + goto Cleanup; + } + + //close the hash + if(!NT_SUCCESS(status = BCryptFinishHash( + hHash, + pbHash, + cbHash, + 0))) + { + wprintf(L"**** Error 0x%x returned by BCryptFinishHash\n", status); + goto Cleanup; + } + + wprintf(L"Success!\n"); + +Cleanup: + + if(hAlg) + { + BCryptCloseAlgorithmProvider(hAlg,0); + } + + if (hHash) + { + BCryptDestroyHash(hHash); + } + + if(pbHashObject) + { + HeapFree(GetProcessHeap(), 0, pbHashObject); + } + + if(pbHash) + { + HeapFree(GetProcessHeap(), 0, pbHash); + } + +} \ No newline at end of file diff --git a/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj b/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj index f8ef14a..468649b 100644 --- a/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj +++ b/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj @@ -132,6 +132,7 @@ + diff --git a/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj.filters b/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj.filters index e39897e..5bd351c 100644 --- a/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj.filters +++ b/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj.filters @@ -39,6 +39,9 @@ 源文件 + + 源文件 + diff --git a/TestNetTunnelSDK/TestNetTunnelSDK.cpp b/TestNetTunnelSDK/TestNetTunnelSDK.cpp index cf94439..89f2cd8 100644 --- a/TestNetTunnelSDK/TestNetTunnelSDK.cpp +++ b/TestNetTunnelSDK/TestNetTunnelSDK.cpp @@ -17,8 +17,10 @@ TEST_MODULE_INITIALIZE(ModuleInitialize) { "http://xajhuang.com:9276", TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_" "windows\\NetTunnelApp\\bin\\Debug\\utest.log"), - LOG_DEBUG, + LOG_TRACE, false)); + Assert::AreEqual(0, EnableVerifySignature(TEXT("123"), TEXT("123456"))); + Assert::AreEqual(0, EnableSCGProxy(true, TEXT("efc.xajhuang.com"), 10001)); } TEST_MODULE_CLEANUP(ModuleCleanup) { @@ -195,8 +197,6 @@ public: Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("123455"), &pCfg)); } - - TEST_METHOD(TestClientProgress) { PUSER_CLIENT_CONFIG pCfg = nullptr; Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("1323245235"), &pCfg)); @@ -208,8 +208,9 @@ public: //EnableSCGProxy(true, 10000); - //Assert::AreEqual(RET_OK, RemoteWireGuardControl(false)); - //Assert::AreEqual(RET_OK, LocalWireGuardControl(false, false)); + //Sleep(30 * 1000); + Assert::AreEqual(RET_OK, RemoteWireGuardControl(false)); + Assert::AreEqual(RET_OK, LocalWireGuardControl(false, false)); } TEST_METHOD(TestClientProgressFree) { @@ -218,8 +219,8 @@ public: } TEST_METHOD(TestGetSDKErrorMessage) { - const CHAR* pErrStr = GetSDKErrorMessage(ERR_INPUT_PARAMS); - Assert::AreEqual(pErrStr, "ERR_INPUT_PARAMS"); + const CHAR *pErrStr = GetSDKErrorMessage(ERR_INPUT_PARAMS); + Assert::AreEqual(pErrStr, "ERR_INPUT_PARAMS"); } }; } \ No newline at end of file diff --git a/TestNetTunnelSDK/TestNetTunnelSDK.vcxproj b/TestNetTunnelSDK/TestNetTunnelSDK.vcxproj index 25d3704..d0b9ad2 100644 --- a/TestNetTunnelSDK/TestNetTunnelSDK.vcxproj +++ b/TestNetTunnelSDK/TestNetTunnelSDK.vcxproj @@ -92,7 +92,7 @@ Use Level3 true - ..\NetTunnelSDK\sdk;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + ..\NetTunnelSDK\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) _DEBUG;%(PreprocessorDefinitions) true pch.h