mirror of
https://github.com/unslothai/unsloth.git
synced 2026-08-19 13:53:58 +00:00
* Sign the NSIS plugin DLLs, and fail the release on any unsigned file Both 0.1.51-beta and 0.1.512-beta ship four unsigned DLLs: NSISdl.dll, System.dll, StartMenu.dll and nsDialogs.dll. Only nsis_tauri_utils.dll carries the Unsloth AI Inc. signature. tauri-bundler is doing the work already. When a signing identity is configured it copies Plugins/x86-unicode aside, signs all five files listed in NSIS_PLUGIN_FILES, and exports the copy as the NSISPLUGINS environment variable. Nothing consumes it: no NSIS template references $%NSISPLUGINS%, and the only plugin directory added is ADDITIONALPLUGINSPATH, which points at the copy's additional subdirectory and holds exactly one file. So one DLL resolves from the signed copy and the other four fall back to the default unsigned one. Add the directory in our template, guarded so unsigned local builds still compile, and add a check that unpacks each bundle and fails listing every unsigned executable rather than stopping at the first. * Fail the signing gate when a bundle cannot be unpacked 7-Zip leaves a partial tree behind on error and can fall back to its PE handler, which yields sections rather than the payload. Both cases passed the gate having verified nothing. Move !addplugindir above the includes so the signed copy is registered before any plugin is packed. * Tighten comments on the bundle signing gate * Sign the bundled install script and gate on it install.ps1 ships as a bundle resource and is the first thing the app runs after install, but the bundler never signs it and the gate did not look at scripts. Sign it before the build packs it in, and add .ps1/.psm1 to the checked set. Verified on a Windows runner that signtool attaches a valid signature to a .ps1; trusted-signing-cli lists ps1 as supported and does not filter by extension. * Tighten comments on the bundle signing gate * Reduce the Windows false positive surface Three changes, none of which alter behaviour: install.rs no longer passes -WindowStyle Hidden -ExecutionPolicy Bypass to powershell.exe. CREATE_NO_WINDOW already suppresses the console and the NSIS-extracted script carries no mark-of-the-web, so RemoteSigned loads it. That flag pair is the command line Microsoft ships as a detection test. install.ps1 installs uv from a pinned, SHA-256 verified release archive instead of evaluating a downloaded script in-process. installer.nsi fills in CompanyName and InternalName, which upstream's template leaves empty. * Match astral's installer on unmanaged installs, mirrors, and the PATH probe UV_UNMANAGED_INSTALL forces no-modify-path in astral's installer, so it must here too, and honour UV_INSTALLER_GHE_BASE_URL / UV_INSTALLER_GITHUB_BASE_URL so a mirrored environment still works. Every mirror serves the same asset, so the pinned hash is unchanged; UV_DOWNLOAD_URL stays unhonoured because it points at an arbitrary version the pin would then reject. Record where uv actually landed. Refresh-SessionPath rebuilds PATH machine first and drops the in-process prepend, and the recovery probe never checked the XDG_DATA_HOME or unmanaged destinations, so a good install could still report failure. Required by the change above, which leaves that prepend as the only thing putting uv on PATH. * Tighten comments on the false positive reduction changes --------- Co-authored-by: danielhanchen <danielhanchen@users.noreply.github.com>
93 lines
3.6 KiB
PowerShell
93 lines
3.6 KiB
PowerShell
# Fail if any executable inside a Windows bundle is unsigned. NSIS runs its
|
|
# plugin DLLs from $PLUGINSDIR, so a signed installer proves nothing about them.
|
|
|
|
param(
|
|
# Bundles to unpack; every PE inside is verified.
|
|
[Parameter(Mandatory = $true)][string[]] $Path,
|
|
# 7-Zip, preinstalled on windows-latest.
|
|
[string] $SevenZip = '7z',
|
|
# Known-unsigned leaf names to accept. Keep empty where possible.
|
|
[string[]] $Allow = @()
|
|
)
|
|
|
|
$ErrorActionPreference = 'Continue'
|
|
# .ps1/.psm1 included: install.ps1 ships as a bundle resource and runs on first
|
|
# launch. Authenticode covers scripts, and Smart App Control checks them.
|
|
$exeExtensions = @('.exe', '.dll', '.sys', '.ocx', '.cpl', '.scr', '.ps1', '.psm1')
|
|
|
|
$unsigned = @()
|
|
$checked = 0
|
|
|
|
foreach ($bundle in $Path) {
|
|
if (-not (Test-Path $bundle -PathType Leaf)) {
|
|
Write-Host "::error::bundle not found: $bundle"
|
|
exit 1
|
|
}
|
|
$name = Split-Path $bundle -Leaf
|
|
Write-Host ''
|
|
Write-Host "=== $name ==="
|
|
|
|
$sig = Get-AuthenticodeSignature $bundle
|
|
$checked++
|
|
if ($sig.Status -ne 'Valid') {
|
|
Write-Host " UNSIGNED $name ($($sig.Status))"
|
|
$unsigned += [pscustomobject]@{ Bundle = $name; File = $name; Status = [string]$sig.Status }
|
|
} else {
|
|
Write-Host " signed $name <- $($sig.SignerCertificate.Subject)"
|
|
}
|
|
|
|
$dest = Join-Path $env:RUNNER_TEMP ("sigcheck-" + [System.IO.Path]::GetFileNameWithoutExtension($name))
|
|
Remove-Item $dest -Recurse -Force -ErrorAction SilentlyContinue
|
|
& $SevenZip x -y "-o$dest" $bundle | Out-Null
|
|
# 7-Zip leaves a partial tree behind on error, so a created dir proves nothing.
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "::error::7-Zip exited $LASTEXITCODE unpacking $name; contents not verified"
|
|
exit 1
|
|
}
|
|
if (-not (Test-Path $dest)) {
|
|
Write-Host "::error::could not unpack $name; cannot verify its contents"
|
|
exit 1
|
|
}
|
|
|
|
$inner = Get-ChildItem $dest -Recurse -File |
|
|
Where-Object { $exeExtensions -contains $_.Extension.ToLower() }
|
|
# No hits means 7-Zip dumped PE sections, not that the payload is clean.
|
|
if (-not $inner) {
|
|
Write-Host "::error::no executable payload found inside $name; contents not verified"
|
|
exit 1
|
|
}
|
|
|
|
foreach ($f in ($inner | Sort-Object Name)) {
|
|
$checked++
|
|
$s = Get-AuthenticodeSignature $f.FullName
|
|
if ($s.Status -eq 'Valid') {
|
|
Write-Host (" signed {0}" -f $f.Name)
|
|
} elseif ($Allow -contains $f.Name) {
|
|
Write-Host (" ALLOWED {0} ({1}) - explicitly accepted as unsigned" -f $f.Name, $s.Status)
|
|
} else {
|
|
# UnknownError = no signature or unbuilt chain; StatusMessage tells which.
|
|
Write-Host (" UNSIGNED {0} ({1}) {2}" -f $f.Name, $s.Status, $s.StatusMessage)
|
|
$unsigned += [pscustomobject]@{ Bundle = $name; File = $f.Name; Status = [string]$s.Status }
|
|
}
|
|
}
|
|
Remove-Item $dest -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
Write-Host ''
|
|
Write-Host "checked $checked file(s) across $($Path.Count) bundle(s)"
|
|
|
|
if (-not $unsigned) {
|
|
Write-Host 'Every executable in every bundle is validly signed.'
|
|
exit 0
|
|
}
|
|
|
|
Write-Host ''
|
|
Write-Host '================ UNSIGNED FILES ================'
|
|
$unsigned | Format-Table Bundle, File, Status -AutoSize | Out-String | Write-Host
|
|
foreach ($u in $unsigned) {
|
|
Write-Host "::error file=$($u.File)::$($u.File) in $($u.Bundle) is $($u.Status) and needs signing"
|
|
}
|
|
Write-Host ''
|
|
Write-Host 'These ship inside the installer and land on the user machine.'
|
|
Write-Host 'For NSIS plugin DLLs see the NSISPLUGINS note in windows/installer.nsi.'
|
|
exit 1
|