release: Mark VIII 1.0
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
param(
|
||||
[string]$PagerHost = "172.16.52.1",
|
||||
[string]$User = "root",
|
||||
[string]$Password = "",
|
||||
[string]$SshKey = "",
|
||||
[string]$BuildDir = "",
|
||||
[switch]$NoPortalRefresh
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Root = Split-Path -Parent $PSScriptRoot
|
||||
$PayloadKey = "pager-webui"
|
||||
$PayloadCategory = "remote_access"
|
||||
$PayloadDir = Join-Path $Root "payload\user\$PayloadCategory\$PayloadKey"
|
||||
if (-not (Test-Path $PayloadDir)) { throw "Payload dir not found: $PayloadDir" }
|
||||
|
||||
if (-not $BuildDir) { $BuildDir = Join-Path $Root "build" }
|
||||
$OutDir = Join-Path $BuildDir $PayloadKey
|
||||
New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
|
||||
|
||||
# --- 1. Stage payload tree -------------------------------------------------
|
||||
$Stage = Join-Path $OutDir "stage"
|
||||
if (Test-Path $Stage) { Remove-Item -Recurse -Force $Stage }
|
||||
New-Item -ItemType Directory -Force -Path (Join-Path $Stage "user\$PayloadCategory") | Out-Null
|
||||
Copy-Item -Recurse $PayloadDir (Join-Path $Stage "user\$PayloadCategory\$PayloadKey")
|
||||
|
||||
# --- 2. Build zip (portal format: payload-<b64>.zip) -----------------------
|
||||
$b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($PayloadKey)).TrimEnd('=').Replace('+','-').Replace('/','_')
|
||||
$ZipName = "payload-$b64.zip"
|
||||
$ZipPath = Join-Path $OutDir $ZipName
|
||||
if (Test-Path $ZipPath) { Remove-Item -Force $ZipPath }
|
||||
|
||||
Add-Type -AssemblyName System.IO.Compression
|
||||
$zip = New-Object System.IO.Compression.ZipArchive([IO.File]::Open($ZipPath, 'Create'), [IO.Compression.ZipArchiveMode]::Create)
|
||||
try {
|
||||
Get-ChildItem -Recurse -File $Stage | Where-Object {
|
||||
$_.FullName -notmatch '[\\/]__pycache__[\\/]' -and $_.Extension -ne '.pyc'
|
||||
} | ForEach-Object {
|
||||
$rel = $_.FullName.Substring($Stage.Length + 1).Replace('\', '/')
|
||||
$entry = $zip.CreateEntry($rel, [IO.Compression.CompressionLevel]::Optimal)
|
||||
$es = $entry.Open()
|
||||
$bytes = [IO.File]::ReadAllBytes($_.FullName)
|
||||
if ($rel -match '(^|/)(payload\.sh|pagerwebui\.init)$') {
|
||||
$bytes = [byte[]]($bytes | Where-Object { $_ -ne 13 })
|
||||
}
|
||||
$es.Write($bytes, 0, $bytes.Length)
|
||||
$es.Close()
|
||||
}
|
||||
} finally { $zip.Dispose() }
|
||||
|
||||
# --- 3. Manifest with generated fields ------------------------------------
|
||||
$hash = (Get-FileHash -Algorithm SHA256 $ZipPath).Hash.ToLower()
|
||||
$manifest = Get-Content -Raw (Join-Path $PayloadDir "_hak5_manifest.json") | ConvertFrom-Json
|
||||
$manifest.time = [int64]([DateTimeOffset]::UtcNow.ToUnixTimeSeconds())
|
||||
$manifest.last_hash = $hash
|
||||
$manifest.zip = $ZipName
|
||||
$manifest = $manifest | ConvertTo-Json
|
||||
Set-Content -Path (Join-Path $OutDir "_hak5_manifest.json") -Value $manifest -Encoding ascii
|
||||
Write-Host "Built: $ZipPath"
|
||||
|
||||
# --- 4. Credentials / transport -------------------------------------------
|
||||
if ($SshKey) {
|
||||
$sshBase = "$User@$PagerHost"
|
||||
$scp = "scp -i `"$SshKey`""
|
||||
$ssh = "ssh -i `"$SshKey`""
|
||||
} elseif (Get-Command sshpass -ErrorAction SilentlyContinue) {
|
||||
if (-not $Password) { $Password = Read-Host -AsSecureString "Pager root password"; $Password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)) }
|
||||
$sshBase = "$User@$PagerHost"
|
||||
$scp = "sshpass -p `"$Password`" scp"
|
||||
$ssh = "sshpass -p `"$Password`" ssh"
|
||||
} else {
|
||||
Write-Host "`nNo sshpass or -SshKey found. Run these manually (password prompts appear):"
|
||||
Write-Host " scp `"$ZipPath`" $User@${PagerHost}:/tmp/"
|
||||
Write-Host " ssh $User@$PagerHost `"cd /root/payloads && unzip -q -o /tmp/$ZipName && chmod +x user/general/$PayloadKey/payload.sh && rm -f /tmp/$ZipName`""
|
||||
Write-Host "Then re-run this script with -SshKey, or install sshpass."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- 5. Upload + extract on device ----------------------------------------
|
||||
& cmd /c "$scp `"$ZipPath`" `"$(Join-Path $OutDir '_hak5_manifest.json')`" ${sshBase}:/tmp/" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) { throw "SCP failed" }
|
||||
|
||||
$remotePayloadDir = "user/$PayloadCategory/$PayloadKey"
|
||||
$legacyPayloadDir = "user/general/$PayloadKey"
|
||||
$remoteCmd = "cd /root/payloads && rm -rf $remotePayloadDir $legacyPayloadDir && unzip -q -o /tmp/$ZipName && cp /tmp/_hak5_manifest.json $remotePayloadDir/_hak5_manifest.json && chmod +x $remotePayloadDir/payload.sh && chmod -R 755 $remotePayloadDir/www && rm -f /tmp/$ZipName /tmp/_hak5_manifest.json && if [ -x /etc/init.d/pagerwebui ] && /etc/init.d/pagerwebui running >/dev/null 2>&1; then /etc/init.d/pagerwebui restart; fi && echo EXTRACT_OK"
|
||||
& cmd /c "$ssh $sshBase `"$remoteCmd`""
|
||||
if ($LASTEXITCODE -ne 0) { throw "Remote extraction failed" }
|
||||
Write-Host "Installed to /root/payloads/$remotePayloadDir/"
|
||||
|
||||
# --- 6. Portal refresh (best-effort) --------------------------------------
|
||||
if (-not $NoPortalRefresh) {
|
||||
if (-not $Password) {
|
||||
Write-Host "Skipping portal refresh (no password supplied). Run the payload from the on-device menu to verify."
|
||||
} else {
|
||||
# Base64 the remote command so cmd/ssh quoting cannot mangle the JSON body.
|
||||
$loginCmd = "curl -s -X POST http://127.0.0.1:1471/api/login -d '{""username"":""root"",""password"":""$Password""}'"
|
||||
$b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($loginCmd))
|
||||
$tokenJson = & cmd /c "$ssh $sshBase `"echo $b64 | base64 -d | sh`""
|
||||
$tokenJson = [string]$tokenJson -replace '\x1b\[[0-9;?]*[A-Za-z]', ''
|
||||
$token = ($tokenJson | ConvertFrom-Json).token
|
||||
if ($token) {
|
||||
$refreshCmd = "curl -fsS -X POST http://127.0.0.1:1471/api/payloads/portal/refresh -H 'Authorization: Bearer $token'"
|
||||
$b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($refreshCmd))
|
||||
& cmd /c "$ssh $sshBase `"echo $b64 | base64 -d | sh`"" | Out-Null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "Portal refreshed. The payload should appear in the on-device Payloads menu / Virtual Pager portal."
|
||||
} else {
|
||||
Write-Warning "Portal refresh failed; the local payload installation is still complete."
|
||||
}
|
||||
} else {
|
||||
Write-Host "Login to portal refresh failed; the payload is installed as a directory - run it from the menu."
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Host "Deploy complete. Run payload.sh from the Pager menu, then browse http://${PagerHost}:8080/"
|
||||
Reference in New Issue
Block a user