OCT 1. 平台侧接口协议支持 HMAC 签名验证

2. 完成 TCP、UDP SCG接入联调
This commit is contained in:
黄昕 2023-08-14 09:20:25 +08:00
parent 728e645d14
commit 4eb3a1da22
22 changed files with 600 additions and 115 deletions

View File

@ -75,6 +75,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_C3B25B99ADE3C49D4C09315B7B9AF773"
"OwnerKey" = "8:_536090BAB697484B8E206852993F24BA"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_CAF1EAED19FEB8585EE0E5550C6CD814" "MsmKey" = "8:_CAF1EAED19FEB8585EE0E5550C6CD814"
"OwnerKey" = "8:_536090BAB697484B8E206852993F24BA" "OwnerKey" = "8:_536090BAB697484B8E206852993F24BA"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -388,6 +394,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CAF1EAED19FEB8585EE0E5550C6CD814"
{ {
"SourcePath" = "8:VCRUNTIME140D.dll" "SourcePath" = "8:VCRUNTIME140D.dll"
@ -567,7 +593,7 @@
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:SCCSDK" "ProductName" = "8:SCCSDK"
"ProductCode" = "8:{0F21F61E-F559-45D3-9390-20D2563CC2F8}" "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}" "UpgradeCode" = "8:{30151F2E-31C5-44AC-82C4-5FCF9D54BCF3}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"

View File

@ -45,8 +45,8 @@ public partial class MainForm : Form
var path = Environment.CurrentDirectory + "\\tunnelsdk_" + var path = Environment.CurrentDirectory + "\\tunnelsdk_" +
string.Format("{0:yyyyMMdd}", DateTime.Now) + ".log"; string.Format("{0:yyyyMMdd}", DateTime.Now) + ".log";
//NetTunnelLib.InitTunnelSDKLog(path, LogLevel.LOG_DEBUG); //NetTunnelLib.InitTunnelSDKLog(path, LogLevel.LOG_DEBUG);
NetTunnelLib.TunnelSDKInitEnv(Environment.CurrentDirectory, "http://xajhuang.com:9276", path, LogLevel.LOG_DEBUG, menuSetModeServer.Checked); NetTunnelLib.TunnelSDKInitEnv(Environment.CurrentDirectory, "http://xajhuang.com:9276", path, LogLevel.LOG_TRACE, menuSetModeServer.Checked);
//NetTunnelLib.EnableSCGProxy(true, "efc.xajhuang.com", 10000); NetTunnelLib.EnableSCGProxy(true, "efc.xajhuang.com", 10001);
GetCurrentNetCard(); GetCurrentNetCard();
NetCardMenuItems menuItems = new NetCardMenuItems(_curNetCard); NetCardMenuItems menuItems = new NetCardMenuItems(_curNetCard);

View File

@ -233,6 +233,9 @@ int RemoteCtrlSvrCfgUserTunnel(int vmId, const TCHAR *pCliNetwork) {
GetIpV4InfoFromCIDR(pUserCfg->cliAddress, &ipInfo); GetIpV4InfoFromCIDR(pUserCfg->cliAddress, &ipInfo);
req.msgContent.cliTunnelAddr = ipInfo.ip; req.msgContent.cliTunnelAddr = ipInfo.ip;
GetGlobalCfgInfo()->curConnVmId = vmId;
SPDLOG_DEBUG(TEXT("Current VMID: {0}"), vmId);
// 连接到服务端控制服务 // 连接到服务端控制服务
InitControlServer(pUserCfg->pVMConfig[i].scgGateWay); InitControlServer(pUserCfg->pVMConfig[i].scgGateWay);
@ -263,7 +266,6 @@ int RemoteCtrlSvrCfgUserTunnel(int vmId, const TCHAR *pCliNetwork) {
return ret; return ret;
} }
GetGlobalCfgInfo()->curConnVmId = vmId;
return ERR_SUCCESS; return ERR_SUCCESS;
} }
} }
@ -427,7 +429,7 @@ int GetUserServerConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_SE
req.msgContent.token = pToken; req.msgContent.token = pToken;
req.msgContent.user = pUser->userName; req.msgContent.user = pUser->userName;
ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp); ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp, true);
if (ret != ERR_SUCCESS) { if (ret != ERR_SUCCESS) {
return ret; return ret;
@ -483,14 +485,12 @@ int GetUserClientConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CL
req.msgContent.token = pToken; req.msgContent.token = pToken;
req.msgContent.user = pUserName; req.msgContent.user = pUserName;
ret = ProtolPostMessage(GET_CLIENTCFG_PATH, &req, &rsp); ret = ProtolPostMessage(GET_CLIENTCFG_PATH, &req, &rsp, true);
if (ret != ERR_SUCCESS) { if (ret != ERR_SUCCESS) {
return ret; return ret;
} }
pUserCfg->scgCtrlAppId = rsp.msgContent.scgCtrlAppId;
pUserCfg->scgTunnelAppId = rsp.msgContent.scgTunnelAppId;
StringCbCopy(pUserCfg->cliPrivateKey, 64, rsp.msgContent.cliPrivateKey.c_str()); StringCbCopy(pUserCfg->cliPrivateKey, 64, rsp.msgContent.cliPrivateKey.c_str());
StringCbCopy(pUserCfg->cliPublicKey, 64, rsp.msgContent.cliPublicKey.c_str()); StringCbCopy(pUserCfg->cliPublicKey, 64, rsp.msgContent.cliPublicKey.c_str());
StringCbCopy(pUserCfg->cliAddress, MAX_IP_LEN, rsp.msgContent.cliAddress.c_str()); StringCbCopy(pUserCfg->cliAddress, MAX_IP_LEN, rsp.msgContent.cliAddress.c_str());

View File

@ -4,14 +4,14 @@
#include "misc.h" #include "misc.h"
#include <bcrypt.h> #include <bcrypt.h>
#include <wincrypt.h>
#include <shlwapi.h> #include <shlwapi.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#pragma comment(lib, "Bcrypt.lib") #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 NT_FAILED(s) (((NTSTATUS)(s)) < 0)
//#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
static const LPCWSTR g_BcryptHash[] = { static const LPCWSTR g_BcryptHash[] = {
BCRYPT_MD2_ALGORITHM, BCRYPT_MD2_ALGORITHM,
@ -23,7 +23,7 @@ static const LPCWSTR g_BcryptHash[] = {
BCRYPT_SHA512_ALGORITHM, 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; HANDLE hFile;
BYTE rgbFile[1024]; BYTE rgbFile[1024];
DWORD cbRead = 0; DWORD cbRead = 0;
@ -157,3 +157,137 @@ int CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]) {
return ERR_SUCCESS; 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<PBYTE>(&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<PBYTE>(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<PBYTE>(&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<PBYTE>(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;
}

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
// Windows 头文件 // Windows 头文件
#include <windows.h> #include <windows.h>

View File

@ -68,6 +68,8 @@ typedef struct {
USER_CONFIG userCfg; ///< 用户配置项 USER_CONFIG userCfg; ///< 用户配置项
SCG_PROXY_INFO scgProxy; ///< SCG UDP 代理信息 SCG_PROXY_INFO scgProxy; ///< SCG UDP 代理信息
int curConnVmId; ///< 当前连接的VM int curConnVmId; ///< 当前连接的VM
TCHAR clientId[MAX_PATH]; ///< 客户端验证签名 ID
TCHAR clientSecret[MAX_PATH]; ///< 客户端验证签名秘钥
} SDK_CONFIG, *PSDK_CONFIG; } SDK_CONFIG, *PSDK_CONFIG;
#ifdef __cplusplus // If used by C++ code, #ifdef __cplusplus // If used by C++ code,

View File

@ -2174,7 +2174,7 @@ inline std::string from_i_to_hex(size_t n) {
static const auto charset = "0123456789abcdef"; static const auto charset = "0123456789abcdef";
std::string ret; std::string ret;
do { do {
ret = charset[n & 15] + ret; ret = charset[n & 15] + ret;
n >>= 4; n >>= 4;
} while (n > 0); } while (n > 0);
return ret; return ret;
@ -2224,7 +2224,7 @@ inline std::string base64_encode(const std::string &in) {
auto valb = -6; auto valb = -6;
for (auto c : in) { for (auto c : in) {
val = (val << 8) + static_cast<uint8_t>(c); val = (val << 8) + static_cast<uint8_t>(c);
valb += 8; valb += 8;
while (valb >= 0) { while (valb >= 0) {
out.push_back(lookup[(val >> valb) & 0x3F]); 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 { data_sink.write = [&](const char *d, size_t l) -> bool {
if (ok) { if (ok) {
data_available = l > 0; data_available = l > 0;
offset += l; offset += l;
std::string payload; std::string payload;
@ -4311,8 +4311,8 @@ inline bool redirect(T &cli,
const std::string &path, const std::string &path,
const std::string &location, const std::string &location,
Error &error) { Error &error) {
Request new_req = req; Request new_req = req;
new_req.path = path; new_req.path = path;
new_req.redirect_count_ -= 1; new_req.redirect_count_ -= 1;
if (res.status == 303 && (req.method != "GET" && req.method != "HEAD")) { 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<typename T> template<typename T>
inline std::string serialize_multipart_formdata_item_begin(const T &item, const std::string &boundary) { 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 + "\""; body += "Content-Disposition: form-data; name=\"" + item.name + "\"";
if (!item.filename.empty()) { if (!item.filename.empty()) {
body += "; filename=\"" + item.filename + "\""; body += "; filename=\"" + item.filename + "\"";
@ -4800,7 +4800,7 @@ inline std::pair<size_t, size_t> 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) { 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 += std::to_string(offset);
field += "-"; field += "-";
field += std::to_string(offset + length - 1); 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<CFArrayRef> &certs) { inline bool retrieve_certs_from_keychain(CFObjectPtr<CFArrayRef> &certs) {
CFStringRef keys[] = {kSecClass, kSecMatchLimit, kSecReturnRef}; CFStringRef keys[] = {kSecClass, kSecMatchLimit, kSecReturnRef};
CFTypeRef values[] = {kSecClassCertificate, kSecMatchLimitAll, kCFBooleanTrue}; CFTypeRef values[] = {kSecClassCertificate, kSecMatchLimitAll, kCFBooleanTrue};
CFObjectPtr<CFDictionaryRef> query(CFDictionaryCreate(nullptr, CFObjectPtr<CFDictionaryRef> query(CFDictionaryCreate(nullptr,
reinterpret_cast<const void **>(keys), reinterpret_cast<const void **>(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) { inline bool load_system_certs_on_macos(X509_STORE *store) {
auto result = false; auto result = false;
CFObjectPtr<CFArrayRef> certs(nullptr, cf_object_ptr_deleter); CFObjectPtr<CFArrayRef> certs(nullptr, cf_object_ptr_deleter);
if (retrieve_certs_from_keychain(certs) && certs) { if (retrieve_certs_from_keychain(certs) && certs) {
result = add_certs_to_x509_store(certs.get(), store); result = add_certs_to_x509_store(certs.get(), store);
@ -5276,7 +5276,7 @@ inline void hosted_at(const std::string &hostname, std::vector<std::string> &add
inline std::string append_query_params(const std::string &path, const Params &params) { inline std::string append_query_params(const std::string &path, const Params &params) {
std::string path_with_query = path; std::string path_with_query = path;
const static std::regex re("[^?]+\\?.*"); 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); path_with_query += delm + detail::params_to_query_str(params);
return path_with_query; return path_with_query;
} }
@ -5511,7 +5511,7 @@ inline ssize_t SocketStream::read(char *ptr, size_t size) {
#ifdef _WIN32 #ifdef _WIN32
size = (std::min)(size, static_cast<size_t>((std::numeric_limits<int>::max)())); size = (std::min)(size, static_cast<size_t>((std::numeric_limits<int>::max)()));
#else #else
size = (std::min)(size, static_cast<size_t>((std::numeric_limits<ssize_t>::max)())); size = (std::min)(size, static_cast<size_t>((std::numeric_limits<ssize_t>::max)()));
#endif #endif
if (read_buff_off_ < read_buff_content_size_) { 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()); assert(socket_requests_are_from_thread_ == std::this_thread::get_id());
} }
socket_requests_in_flight_ += 1; 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_) { 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()) { if (!username.empty() && !password.empty()) {
std::map<std::string, std::string> auth; std::map<std::string, std::string> auth;
if (detail::parse_www_authenticate(res, auth, is_proxy)) { if (detail::parse_www_authenticate(res, auth, is_proxy)) {
Request new_req = req; Request new_req = req;
new_req.authorization_count_ += 1; new_req.authorization_count_ += 1;
new_req.headers.erase(is_proxy ? "Proxy-Authorization" : "Authorization"); new_req.headers.erase(is_proxy ? "Proxy-Authorization" : "Authorization");
new_req.headers.insert(detail::make_digest_authentication_header(req, 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()) { } else if (cur_item < provider_items.size()) {
if (!cur_start) { if (!cur_start) {
const auto &begin = detail::serialize_multipart_formdata_item_begin(provider_items[cur_item], boundary); const auto &begin = detail::serialize_multipart_formdata_item_begin(provider_items[cur_item], boundary);
offset += begin.size(); offset += begin.size();
cur_start = offset; cur_start = offset;
sink.os << begin; sink.os << begin;
} }

View File

@ -75,19 +75,6 @@ int GetInterfaceGUIDByName(const TCHAR *pInterfaceName, GUID *pGuid);
int WaitNetAdapterConnected(const TCHAR *pInterfaceName, int timeOutOfMs); 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 * @brief NetworkCategory Private
* @param[in] pInterfaceName * @param[in] pInterfaceName

View File

@ -131,7 +131,7 @@ template<class T1, class T2>
int ProtolPostMessage(const TCHAR *pUrlPath, int ProtolPostMessage(const TCHAR *pUrlPath,
ProtocolRequest<T1> *pReq, ProtocolRequest<T1> *pReq,
ProtocolResponse<T2> *pRsp, ProtocolResponse<T2> *pRsp,
bool platformServer = true); bool platformServer);
extern template int ProtolPostMessage(const TCHAR *pUrlPath, extern template int ProtolPostMessage(const TCHAR *pUrlPath,
ProtocolRequest<ReqGetUserCfgParams> *pReq, ProtocolRequest<ReqGetUserCfgParams> *pReq,

View File

@ -154,6 +154,34 @@ SCCSDK_API int __cdecl GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts);
*/ */
SCCSDK_API int __cdecl GetInternetIfIndex(int *pIfIndex); 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 * @brief
* @param pSvr * @param pSvr
@ -196,6 +224,14 @@ SCCSDK_API int __cdecl GetUserClientConfigure(const TCHAR *pUserName,
const TCHAR *pToken, const TCHAR *pToken,
PUSER_CLIENT_CONFIG *pCliCfg); PUSER_CLIENT_CONFIG *pCliCfg);
/**
* @brief
* @return 0: 0 @see USER_ERRNO
* - -ERROR_TIMEOUT
* - ERR_SUCCESS
*/
SCCSDK_API int __cdecl StopControlService();
/** /**
* @brief * @brief
* @param[in] vmId ID编号 * @param[in] vmId ID编号

View File

@ -1,6 +1,11 @@
#pragma once #pragma once
#include "sccsdk.h" #include "sccsdk.h"
typedef enum {
WG_TUNNEL_SCG_ID = 3,
WG_CTRL_SCG_ID = 4
} SCG_SVR_ID;
typedef enum { typedef enum {
CHK_SYSTEM_INIT, CHK_SYSTEM_INIT,
CHK_WIREGUARD_CONFIG, CHK_WIREGUARD_CONFIG,
@ -172,8 +177,29 @@ int IsWireGuardServerInstalled(bool *pIsInstalled);
* - -ERR_BCRYPT_FINISHHASH Hash * - -ERR_BCRYPT_FINISHHASH Hash
* - ERR_SUCCESS * - 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -22,14 +22,6 @@ extern "C" {
*/ */
void ConnectServerControlService(const TCHAR *pUserSvrUrl); void ConnectServerControlService(const TCHAR *pUserSvrUrl);
/**
* @brief
* @return 0: 0 @see USER_ERRNO
* - -ERROR_TIMEOUT
* - ERR_SUCCESS
*/
int StopControlService();
/** /**
* @brief WireGuard * @brief WireGuard
* @param[in] pCliPrivateKey * @param[in] pCliPrivateKey

View File

@ -8,25 +8,10 @@
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <spdlog/fmt/bin_to_hex.h>
#define SCG_UDP_HEAD_SIZE (11) #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() { void StopUDPProxyServer() {
const PSCG_PROXY_INFO pProxy = &GetGlobalCfgInfo()->scgProxy; const PSCG_PROXY_INFO pProxy = &GetGlobalCfgInfo()->scgProxy;
pProxy->exitNow = true; pProxy->exitNow = true;
@ -90,6 +75,13 @@ static DWORD UDPProxvRemoteThread(LPVOID lpParameter) {
pProxy->udpProxySock, pProxy->udpProxySock,
ipAddr, ipAddr,
ntohs(pPeerSock->sin_port)); 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); Sleep(100);
@ -98,34 +90,31 @@ static DWORD UDPProxvRemoteThread(LPVOID lpParameter) {
} }
static DWORD UDPProxyRecvThread(LPVOID lpParameter) { static DWORD UDPProxyRecvThread(LPVOID lpParameter) {
bool isRemoteInit = false; bool isRemoteInit = false;
sockaddr_in localWgAddr {}; sockaddr_in localWgAddr {};
sockaddr_in scgAddr {}; sockaddr_in scgAddr {};
unsigned char recvBuf[1500 + SCG_UDP_HEAD_SIZE]; unsigned char recvBuf[1500 + SCG_UDP_HEAD_SIZE];
const PSCG_PROXY_INFO pProxy = &GetGlobalCfgInfo()->scgProxy; std::array<UINT8, 1511> arr;
unsigned char vmid[4]; const PSCG_PROXY_INFO pProxy = &GetGlobalCfgInfo()->scgProxy;
const unsigned int id = htonl(GetGlobalCfgInfo()->curConnVmId); const auto svrId = static_cast<UINT8>(GetGlobalCfgInfo()->userCfg.cliConfig.scgTunnelAppId);
const auto svrId = static_cast<UINT8>(GetGlobalCfgInfo()->userCfg.cliConfig.scgTunnelAppId); char *pRecBuf = reinterpret_cast<char *>(&recvBuf[SCG_UDP_HEAD_SIZE]);
char *pRecBuf = reinterpret_cast<char *>(&recvBuf[SCG_UDP_HEAD_SIZE]);
scgAddr.sin_family = AF_INET; scgAddr.sin_family = AF_INET;
scgAddr.sin_port = htons(pProxy->scgGwPort); scgAddr.sin_port = htons(pProxy->scgGwPort);
InetPton(AF_INET, pProxy->scgIpAddr, &scgAddr.sin_addr.s_addr); InetPton(AF_INET, pProxy->scgIpAddr, &scgAddr.sin_addr.s_addr);
memcpy(vmid, &id, 4);
// 构建 SCG UDP 包头 // 构建 SCG UDP 包头
recvBuf[0] = 0x01; // VERSION recvBuf[0] = 0x01; // VERSION
recvBuf[1] = 0x09; // Length recvBuf[1] = 0x09; // Length
recvBuf[2] = 0xF0; // ++++++ INFO[0] TYPE recvBuf[2] = 0xF0; // ++++++ INFO[0] TYPE
recvBuf[3] = 0x04; // INFO[0] LENGTH recvBuf[3] = 0x04; // INFO[0] LENGTH
recvBuf[4] = vmid[0]; // INFO[0] VMID[0] recvBuf[4] = 0; // INFO[0] VMID[0]
recvBuf[5] = vmid[1]; // INFO[0] VMID[1] recvBuf[5] = 0; // INFO[0] VMID[1]
recvBuf[6] = vmid[2]; // INFO[0] VMID[2] recvBuf[6] = 0; // INFO[0] VMID[2]
recvBuf[7] = vmid[3]; // INFO[0] VMID[3] recvBuf[7] = 0; // INFO[0] VMID[3]
recvBuf[8] = 0xF1; // INFO[1] TYPE recvBuf[8] = 0xF1; // INFO[1] TYPE
recvBuf[9] = 0x01; // INFO[1] LENGTH recvBuf[9] = 0x01; // INFO[1] LENGTH
recvBuf[10] = svrId; // ------ INFO[1] SCG Service ID recvBuf[10] = svrId; // ------ INFO[1] SCG Service ID
pProxy->exitNow = false; pProxy->exitNow = false;
while (!pProxy->exitNow) { while (!pProxy->exitNow) {
@ -155,7 +144,10 @@ static DWORD UDPProxyRecvThread(LPVOID lpParameter) {
} }
if (iRecvBytes != SOCKET_ERROR) { 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) { if (!isRemoteInit) {
HANDLE handle; HANDLE handle;
@ -179,9 +171,24 @@ static DWORD UDPProxyRecvThread(LPVOID lpParameter) {
pProxy->hProxySCGThread = handle; 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包头数据长度 // 增加SCG包头数据长度
iRecvBytes += 11; 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<char *>(recvBuf), reinterpret_cast<char *>(recvBuf),
iRecvBytes, iRecvBytes,
0, 0,

View File

@ -161,7 +161,26 @@ int GetInterfaceNameByGUID(const TCHAR *pGUID, TCHAR ifName[MAX_NETCARD_NAME]) {
reinterpret_cast<void **>(&pNSM)); reinterpret_cast<void **>(&pNSM));
if (hr != S_OK || pNSM == nullptr) { 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<void **>(&pNSM));
}
if (hr != S_OK || pNSM == nullptr) {
SPDLOG_ERROR(TEXT("CoCreateInstance NetSharingManager failed: {0}"), hr);
return -ERR_CREATE_COMMOBJECT; return -ERR_CREATE_COMMOBJECT;
} }

View File

@ -8,6 +8,7 @@
#include "usrerr.h" #include "usrerr.h"
#include <strsafe.h> #include <strsafe.h>
#include <spdlog/fmt/bin_to_hex.h>
#define HTTP_JSON_CONTENT TEXT("application/json") #define HTTP_JSON_CONTENT TEXT("application/json")
@ -21,12 +22,15 @@ int InitControlServer(const TCHAR *pUserSvrUrl) {
g_tunnelHttpCtx = nullptr; g_tunnelHttpCtx = nullptr;
} }
if (GetGlobalCfgInfo()->scgProxy.scgGwPort > 0) { if (UsedSCGProxy()) {
TCHAR scgProxyUrl[MAX_PATH]; TCHAR scgProxyUrl[MAX_PATH];
StringCbPrintf(scgProxyUrl, MAX_PATH, TEXT("http://127.0.0.1:%d"), GetGlobalCfgInfo()->scgProxy.scgGwPort); 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 { } else {
g_tunnelHttpCtx = new httplib::Client(pUserSvrUrl); g_tunnelHttpCtx = new httplib::Client(pUserSvrUrl);
SPDLOG_DEBUG(TEXT("Control Server Unused Proxy: {0}"), pUserSvrUrl);
} }
if (g_tunnelHttpCtx) { if (g_tunnelHttpCtx) {
@ -59,6 +63,12 @@ int InitControlServer(const TCHAR *pUserSvrUrl) {
scgProxy[6] = vmid[2]; scgProxy[6] = vmid[2];
scgProxy[7] = vmid[3]; scgProxy[7] = vmid[3];
if (GetGlobalCfgInfo()->logLevel == spdlog::level::trace) {
std::array<unsigned char, sizeof(scgProxy)> 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<const char *>(p), sizeof(scgProxy), 0); ret = send(sock, reinterpret_cast<const char *>(p), sizeof(scgProxy), 0);
while (ret < static_cast<int>(sizeof(scgProxy))) { while (ret < static_cast<int>(sizeof(scgProxy))) {
@ -66,7 +76,10 @@ int InitControlServer(const TCHAR *pUserSvrUrl) {
ret += send(sock, reinterpret_cast<const char *>(p), sizeof(scgProxy), 0); ret += send(sock, reinterpret_cast<const char *>(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) { 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<PUCHAR>(hashBuf),
lstrlen(hashBuf),
reinterpret_cast<PUCHAR>(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 { } else {
if (g_tunnelHttpCtx == nullptr) { if (g_tunnelHttpCtx == nullptr) {
free(pJson); free(pJson);
@ -178,16 +219,6 @@ int ProtolPostMessage(const TCHAR *pUrlPath,
return ERR_SUCCESS; return ERR_SUCCESS;
} }
int ProtoGetUserConfigure(const TCHAR *pUser, const TCHAR *pToken) {
int ret;
ProtocolRequest<ReqGetUserCfgParams> req;
ProtocolResponse<RspUserSevrCfgParams> rsp;
ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp);
return ret;
}
template int ProtolPostMessage(const TCHAR *pUrlPath, template int ProtolPostMessage(const TCHAR *pUrlPath,
ProtocolRequest<ReqGetUserCfgParams> *pReq, ProtocolRequest<ReqGetUserCfgParams> *pReq,
ProtocolResponse<RspUserSevrCfgParams> *pRsp, ProtocolResponse<RspUserSevrCfgParams> *pRsp,

View File

@ -154,6 +154,34 @@ SCCSDK_API int __cdecl GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts);
*/ */
SCCSDK_API int __cdecl GetInternetIfIndex(int *pIfIndex); 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 * @brief
* @param pSvr * @param pSvr
@ -196,6 +224,14 @@ SCCSDK_API int __cdecl GetUserClientConfigure(const CHAR *pUserName,
const CHAR *pToken, const CHAR *pToken,
PUSER_CLIENT_CONFIG *pCliCfg); PUSER_CLIENT_CONFIG *pCliCfg);
/**
* @brief
* @return 0: 0 @see USER_ERRNO
* - -ERROR_TIMEOUT
* - ERR_SUCCESS
*/
SCCSDK_API int __cdecl StopControlService();
/** /**
* @brief * @brief
* @param[in] vmId ID编号 * @param[in] vmId ID编号

View File

@ -181,6 +181,30 @@ void TunnelSDKUnInit() {
WSACleanup(); 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) { int EnableSCGProxy(bool isEnable, const TCHAR *pSCGIpAddr, int scgPort) {
if (pSCGIpAddr == nullptr || lstrlen(pSCGIpAddr) == 0 || lstrlen(pSCGIpAddr) >= MAX_IP_LEN) { 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; 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); StringCbCopy(g_globalConfig.scgProxy.scgIpAddr, MAX_IP_LEN, ipInfo.hostip);
g_globalConfig.scgProxy.scgGwPort = static_cast<UINT16>(scgPort); g_globalConfig.scgProxy.scgGwPort = static_cast<UINT16>(scgPort);
CreateUDPProxyServer(); CreateUDPProxyServer();

View File

@ -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 <windows.h>
#include <stdio.h>
#include <bcrypt.h>
//#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);
}
}

View File

@ -132,6 +132,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="CryptoExample.cpp" /> <ClCompile Include="CryptoExample.cpp" />
<ClCompile Include="firewall.cpp" /> <ClCompile Include="firewall.cpp" />
<ClCompile Include="HmacSHA256.cpp" />
<ClCompile Include="NetInterface.cpp" /> <ClCompile Include="NetInterface.cpp" />
<ClCompile Include="NetNat.cpp" /> <ClCompile Include="NetNat.cpp" />
<ClCompile Include="NetShare.cpp" /> <ClCompile Include="NetShare.cpp" />

View File

@ -39,6 +39,9 @@
<ClCompile Include="WireGurad.cpp"> <ClCompile Include="WireGurad.cpp">
<Filter>源文件</Filter> <Filter>源文件</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="HmacSHA256.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="common.h"> <ClInclude Include="common.h">

View File

@ -17,8 +17,10 @@ TEST_MODULE_INITIALIZE(ModuleInitialize) {
"http://xajhuang.com:9276", "http://xajhuang.com:9276",
TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_" TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_"
"windows\\NetTunnelApp\\bin\\Debug\\utest.log"), "windows\\NetTunnelApp\\bin\\Debug\\utest.log"),
LOG_DEBUG, LOG_TRACE,
false)); false));
Assert::AreEqual(0, EnableVerifySignature(TEXT("123"), TEXT("123456")));
Assert::AreEqual(0, EnableSCGProxy(true, TEXT("efc.xajhuang.com"), 10001));
} }
TEST_MODULE_CLEANUP(ModuleCleanup) { TEST_MODULE_CLEANUP(ModuleCleanup) {
@ -195,8 +197,6 @@ public:
Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("123455"), &pCfg)); Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("123455"), &pCfg));
} }
TEST_METHOD(TestClientProgress) { TEST_METHOD(TestClientProgress) {
PUSER_CLIENT_CONFIG pCfg = nullptr; PUSER_CLIENT_CONFIG pCfg = nullptr;
Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("1323245235"), &pCfg)); Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("1323245235"), &pCfg));
@ -208,8 +208,9 @@ public:
//EnableSCGProxy(true, 10000); //EnableSCGProxy(true, 10000);
//Assert::AreEqual(RET_OK, RemoteWireGuardControl(false)); //Sleep(30 * 1000);
//Assert::AreEqual(RET_OK, LocalWireGuardControl(false, false)); Assert::AreEqual(RET_OK, RemoteWireGuardControl(false));
Assert::AreEqual(RET_OK, LocalWireGuardControl(false, false));
} }
TEST_METHOD(TestClientProgressFree) { TEST_METHOD(TestClientProgressFree) {
@ -218,7 +219,7 @@ public:
} }
TEST_METHOD(TestGetSDKErrorMessage) { TEST_METHOD(TestGetSDKErrorMessage) {
const CHAR* pErrStr = GetSDKErrorMessage(ERR_INPUT_PARAMS); const CHAR *pErrStr = GetSDKErrorMessage(ERR_INPUT_PARAMS);
Assert::AreEqual(pErrStr, "ERR_INPUT_PARAMS"); Assert::AreEqual(pErrStr, "ERR_INPUT_PARAMS");
} }
}; };

View File

@ -92,7 +92,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\NetTunnelSDK\sdk;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\NetTunnelSDK\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths> <UseFullPaths>true</UseFullPaths>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>