From 8d3a17d1fb069d6b971a178909a6d43fdc2d0d64 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Mon, 13 Jan 2025 14:01:44 -0600 Subject: [PATCH] Common - Check extensions hash (#10144) Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- addons/common/ACE_ExtensionsHashes.hpp | 6 +++ addons/common/config.cpp | 2 + addons/common/functions/fnc_checkFiles.sqf | 45 ++++++++++++++++------ addons/common/initSettings.inc.sqf | 9 +++++ addons/common/stringtable.xml | 3 ++ extension/Makefile.toml | 10 ++++- tools/.vscode/tasks.json | 4 +- tools/getExtensionHash.py | 36 +++++++++++++++++ 8 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 addons/common/ACE_ExtensionsHashes.hpp create mode 100644 tools/getExtensionHash.py diff --git a/addons/common/ACE_ExtensionsHashes.hpp b/addons/common/ACE_ExtensionsHashes.hpp new file mode 100644 index 00000000000..74fe4defab1 --- /dev/null +++ b/addons/common/ACE_ExtensionsHashes.hpp @@ -0,0 +1,6 @@ +class ACE_ExtensionsHashes { + class ace { + dll = "b83c2c9c7c989eaf888c885d13a2fdf4a61d1c5f"; + dll_x64 = "356a61c4bd2aa13556a8ba0b467c819b3b438d6c"; + }; +}; diff --git a/addons/common/config.cpp b/addons/common/config.cpp index f7b27ce3749..f94b1d376cd 100644 --- a/addons/common/config.cpp +++ b/addons/common/config.cpp @@ -75,3 +75,5 @@ class ACE_Tests { mapConfigs = QPATHTOF(dev\test_mapConfigs.sqf); cfgPatches = QPATHTOF(dev\test_cfgPatches.sqf); }; + +#include "ACE_ExtensionsHashes.hpp" diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf index 13ad27a7cb5..8ae67eb04a0 100644 --- a/addons/common/functions/fnc_checkFiles.sqf +++ b/addons/common/functions/fnc_checkFiles.sqf @@ -116,31 +116,52 @@ if (_oldCompats isNotEqualTo []) then { /////////////// // Check extensions /////////////// -private _platform = toLowerANSI (productVersion select 6); +if (hasInterface) then { + private _platform = toLowerANSI (productVersion select 6); -if (_platform in ["linux", "osx"]) then { - // Linux and OSX client ports do not support extensions at all - if (hasInterface) then { + // Check for presence + if (_platform in ["linux", "osx"]) exitWith { + // Linux and OSX client ports do not support extensions at all WARNING("Operating system does not support extensions"); - } else { - INFO("Operating system does not support extensions"); }; -} else { + ("ace" callExtension ["version", []]) params [["_versionEx", "", [""]], ["_returnCode", -1, [-1]]]; if (_returnCode != 0 || {_versionEx == ""}) then { private _errorMsg = format ["Extension not found. [Return Code: %1]", _returnCode]; ERROR(_errorMsg); - - if (hasInterface) then { - ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); - }; + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); } else { _versionEx = _versionEx select [0, 8]; // git hash INFO_1("Extension [Version: %1]",_versionEx); }; -}; + // Check for correct hash + if (GVAR(checkExtensions)) then { + private _allExtensions = allExtensions; + + { + private _extName = configName _x; + private _extensionType = "dll"; + if (productVersion select 7 == "x64") then { _extensionType = format ["%1_x64", _extensionType]; }; + private _expectedHash = getText (_x >> _extensionType); + + private _extensionHash = ""; + { + if ((_x getOrDefault ["name", ""]) == _extName) exitWith { + _extensionHash = _x getOrDefault ["hash", ""]; + }; + } forEach _allExtensions; + TRACE_3("",_extName,_expectedHash,_extensionHash); + + if (_extensionHash != _expectedHash) then { + private _errorMsg = format ["Extension %1 wrong version [%2 vs %3].", _extName, _extensionHash, _expectedHash]; + ERROR(_errorMsg); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); + }; + } forEach ("true" configClasses (configFile >> "ACE_ExtensionsHashes")); + }; +}; /////////////// // Check server version/addons diff --git a/addons/common/initSettings.inc.sqf b/addons/common/initSettings.inc.sqf index 4b3a2fd9c9d..a0a495b094e 100644 --- a/addons/common/initSettings.inc.sqf +++ b/addons/common/initSettings.inc.sqf @@ -29,6 +29,15 @@ private _categorySway = [_category, LSTRING(subcategory_sway)]; 1 ] call CBA_fnc_addSetting; +[ + QGVAR(checkExtensions), + "CHECKBOX", + [LSTRING(checkExtensions_DisplayName)], + _category, + false, + 1 +] call CBA_fnc_addSetting; + [ QGVAR(settingFeedbackIcons), "LIST", diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index fa26901e46b..ece8ece410d 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -409,6 +409,9 @@ 检查 PBO PBO-k ellenőrzése + + Check Extensions + What addons are allowed regardless? Jaké addony jsou povoleny? diff --git a/extension/Makefile.toml b/extension/Makefile.toml index 3002e34dccf..22f16e3ee18 100644 --- a/extension/Makefile.toml +++ b/extension/Makefile.toml @@ -55,5 +55,13 @@ dependencies = ["build_x32_release"] [tasks.debug] dependencies = ["move_x32_debug", "move_x64_debug"] -[tasks.release] +[tasks.updateSigs] +script_runner = "python" +script_extension = "py" +script_runner_args = ["../tools/getExtensionHash.py"] +script = ''' +''' dependencies = ["move_x32_release", "move_x64_release"] + +[tasks.release] +dependencies = ["updateSigs"] diff --git a/tools/.vscode/tasks.json b/tools/.vscode/tasks.json index 277d4bcc85b..ef04bb50f57 100644 --- a/tools/.vscode/tasks.json +++ b/tools/.vscode/tasks.json @@ -119,7 +119,7 @@ } }, { - "label": "Extension: x64", + "label": "Extension: make move_x64_release", "command": "cargo", "options": { "cwd": "${workspaceFolder}" @@ -133,7 +133,7 @@ } }, { - "label": "Extension: Release", + "label": "Extension: make release", "command": "cargo", "options": { "cwd": "${workspaceFolder}" diff --git a/tools/getExtensionHash.py b/tools/getExtensionHash.py new file mode 100644 index 00000000000..fa990218c44 --- /dev/null +++ b/tools/getExtensionHash.py @@ -0,0 +1,36 @@ +import pathlib +import os +import hashlib + +addon_base_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + +extensions = {} + +for file in os.listdir(addon_base_path): + path = pathlib.Path(addon_base_path, file) + extension_type = "dll" + if path.suffix == ".dll": + key = path.stem + if key.endswith("_x64"): + key = key.removesuffix("_x64") + extension_type += "_x64" + print(f"looking at {path}") + with open(path, 'rb') as file_read: + sha1 = hashlib.sha1() + data = file_read.read() + sha1.update(data) + arr = extensions.get(key, {}) + arr[extension_type] = sha1.hexdigest() + extensions[key] = arr + +file_out = pathlib.Path(addon_base_path, "addons", "common", "ACE_ExtensionsHashes.hpp") +with open(file_out, 'w') as file_write: + print(f"class ACE_ExtensionsHashes {{", file=file_write) + for key, values in extensions.items(): + print(f" class {key} {{", file=file_write) + for type, hash in values.items(): + print(f" {type} = \"{hash}\";", file=file_write) + print(f" }};", file=file_write) + print(f"}};", file=file_write) + +print(f"Wrote {len(extensions)} to {file_out}")