diff options
| author | Saikari <[email protected]> | 2026-02-23 18:01:38 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-23 18:01:38 +0300 |
| commit | 3cf862ee32ea653871d4069b56b619a8cf477e38 (patch) | |
| tree | 7ce15c80dc1fa5cbb894e797f0871fd0065e31f1 /core/src | |
| parent | 8ed3f12c86b74cb46e110e56c2ed20d88b242cee (diff) | |
| parent | ea307e0b88527bc61864766c16dfd346470b2d80 (diff) | |
Merge branch 'xmake-io:dev' into em
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/cli/xmake.lua | 2 | ||||
| -rwxr-xr-x | core/src/cli/xmake.sh | 2 | ||||
| -rw-r--r-- | core/src/tbox/inc/haiku/tbox.config.h | 2 | ||||
| -rwxr-xr-x | core/src/tbox/inc/iphoneos/tbox.config.h | 2 | ||||
| -rw-r--r-- | core/src/tbox/inc/solaris/tbox.config.h | 2 | ||||
| m--------- | core/src/tbox/tbox | 0 | ||||
| -rw-r--r-- | core/src/xmake/engine.c | 2 | ||||
| -rw-r--r-- | core/src/xmake/winos/file_signature.c | 217 |
8 files changed, 224 insertions, 5 deletions
diff --git a/core/src/cli/xmake.lua b/core/src/cli/xmake.lua index 2e4b1aea9..98e86b128 100644 --- a/core/src/cli/xmake.lua +++ b/core/src/cli/xmake.lua @@ -29,7 +29,7 @@ target("cli") -- add links if is_plat("windows") then - add_syslinks("ws2_32", "advapi32", "shell32") + add_syslinks("ws2_32", "advapi32", "shell32", "wintrust", "crypt32") add_ldflags("/export:malloc", "/export:free", "/export:memmove") elseif is_plat("android") then add_syslinks("m", "c") diff --git a/core/src/cli/xmake.sh b/core/src/cli/xmake.sh index 12fffe1af..6ae33ef16 100755 --- a/core/src/cli/xmake.sh +++ b/core/src/cli/xmake.sh @@ -19,7 +19,7 @@ target "cli" if is_plat "macosx" && is_config "runtime" "luajit"; then add_ldflags "-all_load" "-pagezero_size 10000" "-image_base 100000000" elif is_plat "mingw"; then - add_ldflags "-static-libgcc" + add_ldflags "-static-libgcc" "-lwintrust" "-lcrypt32" fi # add install files diff --git a/core/src/tbox/inc/haiku/tbox.config.h b/core/src/tbox/inc/haiku/tbox.config.h index 8a9e72ad8..dc61fce45 100644 --- a/core/src/tbox/inc/haiku/tbox.config.h +++ b/core/src/tbox/inc/haiku/tbox.config.h @@ -16,7 +16,7 @@ /*#undef TB_CONFIG_MICRO_ENABLE*/ /*#undef TB_CONFIG_TYPE_HAVE_WCHAR*/ #define TB_CONFIG_TYPE_HAVE_FLOAT 1 -/*#undef TB_CONFIG_FORCE_UTF8*/ +#define TB_CONFIG_FORCE_UTF8 1 /*#undef TB_CONFIG_API_HAVE_DEPRECATED*/ /*#undef TB_CONFIG_EXCEPTION_ENABLE*/ diff --git a/core/src/tbox/inc/iphoneos/tbox.config.h b/core/src/tbox/inc/iphoneos/tbox.config.h index 290786a50..43aa10c8b 100755 --- a/core/src/tbox/inc/iphoneos/tbox.config.h +++ b/core/src/tbox/inc/iphoneos/tbox.config.h @@ -16,7 +16,7 @@ /* #undef TB_CONFIG_MICRO_ENABLE */ /* #undef TB_CONFIG_TYPE_HAVE_WCHAR */ #define TB_CONFIG_TYPE_HAVE_FLOAT 1 -/* #undef TB_CONFIG_FORCE_UTF8 */ +#define TB_CONFIG_FORCE_UTF8 1 /* #undef TB_CONFIG_API_HAVE_DEPRECATED */ /* #undef TB_CONFIG_EXCEPTION_ENABLE */ diff --git a/core/src/tbox/inc/solaris/tbox.config.h b/core/src/tbox/inc/solaris/tbox.config.h index 89bce47bc..25bafd9f6 100644 --- a/core/src/tbox/inc/solaris/tbox.config.h +++ b/core/src/tbox/inc/solaris/tbox.config.h @@ -16,7 +16,7 @@ /*#undef TB_CONFIG_MICRO_ENABLE*/ /*#undef TB_CONFIG_TYPE_HAVE_WCHAR*/ #define TB_CONFIG_TYPE_HAVE_FLOAT 1 -/*#undef TB_CONFIG_FORCE_UTF8*/ +#define TB_CONFIG_FORCE_UTF8 1 /*#undef TB_CONFIG_API_HAVE_DEPRECATED*/ /*#undef TB_CONFIG_EXCEPTION_ENABLE*/ diff --git a/core/src/tbox/tbox b/core/src/tbox/tbox -Subproject ef851bcb6589b6092f5bd3fca4625631237f9bd +Subproject d0138aad74d1dda1fffbee2f6fc0a8f869d8481 diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c index 1a542bc7c..b93b29bb0 100644 --- a/core/src/xmake/engine.c +++ b/core/src/xmake/engine.c @@ -280,6 +280,7 @@ tb_int_t xm_winos_registry_values(lua_State *lua); tb_int_t xm_winos_short_path(lua_State *lua); tb_int_t xm_winos_processes(lua_State* lua); tb_int_t xm_winos_set_error_mode(lua_State *lua); +tb_int_t xm_winos_file_signature(lua_State *lua); #endif // the utf8 functions @@ -487,6 +488,7 @@ static luaL_Reg const g_winos_functions[] = { { "short_path", xm_winos_short_path }, { "processes", xm_winos_processes }, { "set_error_mode", xm_winos_set_error_mode }, + { "file_signature", xm_winos_file_signature }, { tb_null, tb_null }, }; #endif diff --git a/core/src/xmake/winos/file_signature.c b/core/src/xmake/winos/file_signature.c new file mode 100644 index 000000000..3e617294c --- /dev/null +++ b/core/src/xmake/winos/file_signature.c @@ -0,0 +1,217 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file file_signature.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "file_signature" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" +#include <windows.h> +#include <wintrust.h> +#include <softpub.h> +#include <wincrypt.h> + +/* ////////////////////////////////////////////////////////////////////////////////////// + * types + */ + +// the file signature info type +typedef struct __tb_file_signature_info_t { + // is the file digitally signed? + tb_bool_t is_signed; + + // is the signature valid and trusted by the OS? + tb_bool_t is_trusted; + + /* the name of the signer (e.g., "Microsoft Corporation") + tbox uses UTF-8 by default for tb_char_t + */ + tb_char_t signer_name[256]; +} tb_file_signature_info_t; + +/* ////////////////////////////////////////////////////////////////////////////////////// + * private implementation + */ + +static tb_bool_t tb_file_get_signature_info(tb_char_t const* filepath, tb_file_signature_info_t* info) { + tb_assert_and_check_return_val(filepath && info, tb_false); + + // init info + tb_memset(info, 0, sizeof(tb_file_signature_info_t)); + + // convert path + tb_wchar_t wide_path[TB_PATH_MAXN]; + if (!tb_path_absolute_w(filepath, wide_path, TB_PATH_MAXN)) { + return tb_false; + } + + // init file info + WINTRUST_FILE_INFO file_data = {0}; + file_data.cbStruct = sizeof(file_data); + file_data.pcwszFilePath = wide_path; + file_data.hFile = NULL; + file_data.pgKnownSubject = NULL; + + // init trust data + WINTRUST_DATA trust_data = {0}; + trust_data.cbStruct = sizeof(trust_data); + trust_data.dwUIChoice = WTD_UI_NONE; + trust_data.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; + trust_data.dwUnionChoice = WTD_CHOICE_FILE; + trust_data.dwStateAction = WTD_STATEACTION_VERIFY; + trust_data.hWVTStateData = NULL; + trust_data.pwszURLReference = NULL; + trust_data.dwProvFlags = WTD_SAFER_FLAG; + trust_data.dwUIContext = 0; + trust_data.pFile = &file_data; + + // verify trust + GUID guid_action = WINTRUST_ACTION_GENERIC_VERIFY_V2; + LONG status = WinVerifyTrust(NULL, &guid_action, &trust_data); + + // clean up + trust_data.dwStateAction = WTD_STATEACTION_CLOSE; + WinVerifyTrust(NULL, &guid_action, &trust_data); + + // check status + if (status == ERROR_SUCCESS) { + info->is_signed = tb_true; + info->is_trusted = tb_true; + } else if (status == TRUST_E_NOSIGNATURE) { + return tb_true; + } else if (status == TRUST_E_EXPLICIT_DISTRUST || status == TRUST_E_SUBJECT_NOT_TRUSTED) { + info->is_signed = tb_true; + info->is_trusted = tb_false; + } else { + return tb_false; + } + + // extract signer name + if (info->is_signed) { + HCERTSTORE hStore = NULL; + HCRYPTMSG hMsg = NULL; + DWORD dwEncoding = 0; + DWORD dwContentType = 0; + DWORD dwFormatType = 0; + PCMSG_SIGNER_INFO pSignerInfo = NULL; + PCCERT_CONTEXT pCertContext = NULL; + BOOL bResult = FALSE; + + bResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE, + wide_path, + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, + CERT_QUERY_FORMAT_FLAG_BINARY, + 0, + &dwEncoding, + &dwContentType, + &dwFormatType, + &hStore, + &hMsg, + NULL); + + if (bResult) { + DWORD cbSignerInfo = 0; + if (CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &cbSignerInfo)) { + pSignerInfo = (PCMSG_SIGNER_INFO)tb_malloc(cbSignerInfo); + if (pSignerInfo) { + if (CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (void*)pSignerInfo, &cbSignerInfo)) { + CERT_INFO certInfo; + certInfo.Issuer = pSignerInfo->Issuer; + certInfo.SerialNumber = pSignerInfo->SerialNumber; + + pCertContext = CertFindCertificateInStore(hStore, + (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING), + 0, + CERT_FIND_SUBJECT_CERT, + (PVOID)&certInfo, + NULL); + + if (pCertContext) { + tb_wchar_t wName[256] = {0}; + if (CertGetNameStringW(pCertContext, + CERT_NAME_SIMPLE_DISPLAY_TYPE, + 0, + NULL, + wName, + 256)) { + tb_wtoa(info->signer_name, wName, sizeof(info->signer_name)); + } + CertFreeCertificateContext(pCertContext); + } + } + tb_free(pSignerInfo); + } + } + } + + if (hStore) CertCloseStore(hStore, 0); + if (hMsg) CryptMsgClose(hMsg); + } + + return tb_true; +} + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ + +/* get the file signature info + * + * local info = winos.file_signature(filepath) + * { + * is_signed = true, + * is_trusted = true, + * signer_name = "Microsoft Corporation" + * } + */ +tb_int_t xm_winos_file_signature(lua_State *lua) { + tb_assert_and_check_return_val(lua, 0); + + // get the arguments + tb_char_t const *filepath = luaL_checkstring(lua, 1); + tb_check_return_val(filepath, 0); + + // get signature info + tb_file_signature_info_t info = {0}; + if (tb_file_get_signature_info(filepath, &info)) { + lua_newtable(lua); + lua_pushstring(lua, "is_signed"); + lua_pushboolean(lua, info.is_signed); + lua_settable(lua, -3); + + lua_pushstring(lua, "is_trusted"); + lua_pushboolean(lua, info.is_trusted); + lua_settable(lua, -3); + + if (info.is_signed) { + lua_pushstring(lua, "signer_name"); + lua_pushstring(lua, info.signer_name); + lua_settable(lua, -3); + } + return 1; + } + return 0; +} |
