diff --git a/scripts/windows_setup.iss b/scripts/windows_setup.iss index eb8c70b..bb99369 100644 --- a/scripts/windows_setup.iss +++ b/scripts/windows_setup.iss @@ -179,6 +179,8 @@ begin end; end; +function RunSilentSignerPreflight: Boolean; forward; + procedure OpenInstalledClick(Sender: TObject); var ErrorCode: Integer; @@ -341,7 +343,26 @@ begin TrustCheck.Checked := False; ProgressReceipt := AddBackslash(FixedData) + 'updates\setup-progress.json'; + if WizardSilent and (not RunSilentSignerPreflight) then + begin + Log('Refusing silent setup because the pinned identity is missing, lacks its private key, is untrusted, or its provider did not answer safely.'); + Abort; + end; +end; +function RunSilentSignerPreflight: Boolean; +var + Arguments: String; + ResultCode: Integer; +begin + ExtractTemporaryFile('gamgui-signer-preflight.ps1'); + ExtractTemporaryFile('gamgui-signer-preflight-runner.ps1'); + Arguments := '-NoProfile -NonInteractive -ExecutionPolicy Bypass -File ' + + AddQuotes(ExpandConstant('{tmp}\gamgui-signer-preflight-runner.ps1')) + + ' -SigningScript ' + AddQuotes(ExpandConstant('{tmp}\gamgui-signer-preflight.ps1')) + + ' -CertificateSha256 ' + AddQuotes(SilentSigner) + ' -TimeoutSeconds 15'; + Result := Exec('powershell.exe', Arguments, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and + (ResultCode = 0); end; function InitializeUninstall: Boolean; @@ -398,28 +419,10 @@ begin end; function PrepareToInstall(var NeedsRestart: Boolean): String; -var - Arguments: String; - ResultCode: Integer; begin Result := ''; if ExistingInstall then - Result := 'GamGUI is already installed. Open it or uninstall it before running Setup again.' - else if WizardSilent then - begin - { Run the same read-only signer inspection used by the transactional backend - before expanding the large embedded profile. The backend repeats the check - immediately before any application file is copied or signed. } - ExtractTemporaryFile('gamgui-signer-preflight.ps1'); - ExtractTemporaryFile('gamgui-signer-preflight-runner.ps1'); - Arguments := '-NoProfile -NonInteractive -ExecutionPolicy Bypass -File ' + - AddQuotes(ExpandConstant('{tmp}\gamgui-signer-preflight-runner.ps1')) + - ' -SigningScript ' + AddQuotes(ExpandConstant('{tmp}\gamgui-signer-preflight.ps1')) + - ' -CertificateSha256 ' + AddQuotes(SilentSigner) + ' -TimeoutSeconds 15'; - if (not Exec('powershell.exe', Arguments, '', SW_HIDE, ewWaitUntilTerminated, ResultCode)) or - (ResultCode <> 0) then - Result := 'The pinned GamGUI Local identity is missing, does not have its private key, or is not trusted for this Windows user.'; - end; + Result := 'GamGUI is already installed. Open it or uninstall it before running Setup again.'; end; function InitializeSetup: Boolean; @@ -450,7 +453,7 @@ begin Result := False; Exit; end; - { PrepareToInstall runs the shared read-only signer inspection before the + { InitializeWizard runs the shared read-only signer inspection before the large embedded profile is expanded. The transactional backend repeats the exact check before copying or signing the application. } end; diff --git a/tests/test_build_profiles.py b/tests/test_build_profiles.py index 57d9ace..1d67714 100644 --- a/tests/test_build_profiles.py +++ b/tests/test_build_profiles.py @@ -136,8 +136,12 @@ def test_windows_setup_wizard_is_native_offline_and_fail_closed(): assert "Flags: dontcopy solidbreak" not in wizard assert wizard.count("deleteafterinstall solidbreak") == 2 assert "-TimeoutSeconds 15" in wizard - assert "before expanding the large embedded profile" in wizard + assert "before Setup expands either profile" in wizard assert "The transactional backend repeats the" in wizard + assert "function RunSilentSignerPreflight: Boolean;" in wizard + assert "if WizardSilent and (not RunSilentSignerPreflight) then" in wizard + assert "Abort;" in wizard + assert "The pinned GamGUI Local identity is missing" not in wizard assert "-TrustMode Pretrusted -PretrustedSignerSha256" in wizard assert "GetEnv('CI')" not in wizard assert "Refusing a validation-only signer switch in public Setup" in wizard