mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 12:10:49 +00:00
Merge pull request #333 from AikidoSec/endpoint-install-script
Implement Aikido Endpoint installation script
This commit is contained in:
commit
7eb93f6323
5 changed files with 351 additions and 1 deletions
10
.github/workflows/build-and-release.yml
vendored
10
.github/workflows/build-and-release.yml
vendored
|
|
@ -77,6 +77,10 @@ jobs:
|
||||||
sed "s/\$Version = Get-LatestVersion/\$Version = \"${VERSION}\"/" install-scripts/install-safe-chain.ps1 > release-artifacts/install-safe-chain.ps1
|
sed "s/\$Version = Get-LatestVersion/\$Version = \"${VERSION}\"/" install-scripts/install-safe-chain.ps1 > release-artifacts/install-safe-chain.ps1
|
||||||
cp install-scripts/uninstall-safe-chain.sh release-artifacts/uninstall-safe-chain.sh
|
cp install-scripts/uninstall-safe-chain.sh release-artifacts/uninstall-safe-chain.sh
|
||||||
cp install-scripts/uninstall-safe-chain.ps1 release-artifacts/uninstall-safe-chain.ps1
|
cp install-scripts/uninstall-safe-chain.ps1 release-artifacts/uninstall-safe-chain.ps1
|
||||||
|
cp install-scripts/install-endpoint-mac.sh release-artifacts/install-endpoint-mac.sh
|
||||||
|
cp install-scripts/install-endpoint-windows.ps1 release-artifacts/install-endpoint-windows.ps1
|
||||||
|
cp install-scripts/uninstall-endpoint-mac.sh release-artifacts/uninstall-endpoint-mac.sh
|
||||||
|
cp install-scripts/uninstall-endpoint-windows.ps1 release-artifacts/uninstall-endpoint-windows.ps1
|
||||||
|
|
||||||
- name: Upload binaries to existing GitHub Release
|
- name: Upload binaries to existing GitHub Release
|
||||||
env:
|
env:
|
||||||
|
|
@ -94,7 +98,11 @@ jobs:
|
||||||
release-artifacts/install-safe-chain.sh \
|
release-artifacts/install-safe-chain.sh \
|
||||||
release-artifacts/install-safe-chain.ps1 \
|
release-artifacts/install-safe-chain.ps1 \
|
||||||
release-artifacts/uninstall-safe-chain.sh \
|
release-artifacts/uninstall-safe-chain.sh \
|
||||||
release-artifacts/uninstall-safe-chain.ps1
|
release-artifacts/uninstall-safe-chain.ps1 \
|
||||||
|
release-artifacts/install-endpoint-mac.sh \
|
||||||
|
release-artifacts/install-endpoint-windows.ps1 \
|
||||||
|
release-artifacts/uninstall-endpoint-mac.sh \
|
||||||
|
release-artifacts/uninstall-endpoint-windows.ps1
|
||||||
|
|
||||||
publish-npm:
|
publish-npm:
|
||||||
name: Publish to npm
|
name: Publish to npm
|
||||||
|
|
|
||||||
133
install-scripts/install-endpoint-mac.sh
Normal file
133
install-scripts/install-endpoint-mac.sh
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Downloads and installs SafeChain Ultimate endpoint on macOS
|
||||||
|
#
|
||||||
|
# Usage: curl -fsSL <url> | sudo sh -s -- --token <TOKEN>
|
||||||
|
|
||||||
|
set -e # Exit on error
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
INSTALL_URL="https://github.com/AikidoSec/safechain-internals/releases/download/v1.2.5/SafeChainUltimate.pkg"
|
||||||
|
DOWNLOAD_SHA256="abc2b0e6c6a4ca33cd893eeb16744f9f2da90013fb1abac301f5c00c2ad8bc30"
|
||||||
|
TOKEN_FILE="/tmp/aikido_endpoint_token.txt"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
info() {
|
||||||
|
printf "${GREEN}[INFO]${NC} %s\n" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
printf "${RED}[ERROR]${NC} %s\n" "$1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Download file
|
||||||
|
download() {
|
||||||
|
url="$1"
|
||||||
|
dest="$2"
|
||||||
|
|
||||||
|
if command -v curl >/dev/null 2>&1; then
|
||||||
|
curl -fsSL "$url" -o "$dest" || error "Failed to download from $url"
|
||||||
|
elif command -v wget >/dev/null 2>&1; then
|
||||||
|
wget -q "$url" -O "$dest" || error "Failed to download from $url"
|
||||||
|
else
|
||||||
|
error "Neither curl nor wget found. Please install one of them."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify SHA256 checksum
|
||||||
|
verify_checksum() {
|
||||||
|
file="$1"
|
||||||
|
expected="$2"
|
||||||
|
|
||||||
|
actual=$(shasum -a 256 "$file" | awk '{ print $1 }')
|
||||||
|
|
||||||
|
if [ "$actual" != "$expected" ]; then
|
||||||
|
error "Checksum verification failed. Expected: $expected, Got: $actual"
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Checksum verified successfully."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cleanup temporary files
|
||||||
|
cleanup() {
|
||||||
|
if [ -f "$PKG_FILE" ]; then
|
||||||
|
rm -f "$PKG_FILE"
|
||||||
|
fi
|
||||||
|
if [ -f "$TOKEN_FILE" ]; then
|
||||||
|
rm -f "$TOKEN_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse command-line arguments
|
||||||
|
parse_arguments() {
|
||||||
|
TOKEN=""
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--token)
|
||||||
|
if [ -z "${2:-}" ]; then
|
||||||
|
error "--token requires a value"
|
||||||
|
fi
|
||||||
|
TOKEN="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "Unknown argument: $1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main installation
|
||||||
|
main() {
|
||||||
|
parse_arguments "$@"
|
||||||
|
|
||||||
|
# 1. Check if we're running on macOS
|
||||||
|
if [ "$(uname -s)" != "Darwin" ]; then
|
||||||
|
error "This script is only supported on macOS."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if we're running as root
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
error "Root privileges required. Please re-run with sudo, e.g.: curl -fsSL <url> | sudo sh -s -- --token <TOKEN>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if token is provided via command argument
|
||||||
|
if [ -z "$TOKEN" ]; then
|
||||||
|
error "Token is required. Pass it with --token <TOKEN> or enter it when prompted."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate token to prevent injection
|
||||||
|
case "$TOKEN" in
|
||||||
|
*[\"\'\;\`\$\ ]*)
|
||||||
|
error "Invalid token format. Token must not contain quotes, semicolons, backticks, dollar signs, or whitespace."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 2. Download and verify checksum
|
||||||
|
PKG_FILE=$(mktemp /tmp/SafeChainUltimate.XXXXXX.pkg)
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
info "Downloading SafeChain Ultimate..."
|
||||||
|
download "$INSTALL_URL" "$PKG_FILE"
|
||||||
|
|
||||||
|
info "Verifying checksum..."
|
||||||
|
verify_checksum "$PKG_FILE" "$DOWNLOAD_SHA256"
|
||||||
|
|
||||||
|
# 3. Write token to file for the installer
|
||||||
|
printf "%s" "$TOKEN" > "$TOKEN_FILE"
|
||||||
|
|
||||||
|
# 4. Install the package
|
||||||
|
info "Installing SafeChain Ultimate..."
|
||||||
|
installer -pkg "$PKG_FILE" -target /
|
||||||
|
|
||||||
|
info "SafeChain Ultimate installed successfully!"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
100
install-scripts/install-endpoint-windows.ps1
Normal file
100
install-scripts/install-endpoint-windows.ps1
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
# Downloads and installs SafeChain Ultimate endpoint on Windows
|
||||||
|
#
|
||||||
|
# Usage: iex "& { $(iwr '<url>' -UseBasicParsing) } -token <TOKEN>"
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$token
|
||||||
|
)
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
$InstallUrl = "https://github.com/AikidoSec/safechain-internals/releases/download/v1.2.5/SafeChainUltimate.msi"
|
||||||
|
$DownloadSha256 = "c4d1be7bb2128473b8e955244dc186b5d3f091f668b43cdd3d810cff9d38193c"
|
||||||
|
|
||||||
|
# Ensure TLS 1.2 is enabled for downloads
|
||||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
function Write-Info {
|
||||||
|
param([string]$Message)
|
||||||
|
Write-Host "[INFO] $Message" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-Error-Custom {
|
||||||
|
param([string]$Message)
|
||||||
|
Write-Host "[ERROR] $Message" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running as Administrator
|
||||||
|
function Test-Administrator {
|
||||||
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||||
|
$principal = New-Object Security.Principal.WindowsPrincipal($identity)
|
||||||
|
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main installation
|
||||||
|
function Install-Endpoint {
|
||||||
|
# 1. Check if we're running as Administrator
|
||||||
|
if (-not (Test-Administrator)) {
|
||||||
|
Write-Error-Custom "Administrator privileges required. Please run this script in an elevated terminal (Run as Administrator)."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if token is provided, prompt if not
|
||||||
|
if ([string]::IsNullOrWhiteSpace($token)) {
|
||||||
|
$token = Read-Host "Enter your Aikido endpoint token"
|
||||||
|
if ([string]::IsNullOrWhiteSpace($token)) {
|
||||||
|
Write-Error-Custom "Token is required. Pass it with -token <TOKEN> or enter it when prompted."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate token to prevent command/property injection via msiexec
|
||||||
|
if ($token -match '[";`$\s]') {
|
||||||
|
Write-Error-Custom "Invalid token format. Token must not contain quotes, semicolons, backticks, dollar signs, or whitespace."
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. Download the .msi
|
||||||
|
$msiFile = Join-Path $env:TEMP "SafeChainUltimate-$([System.Guid]::NewGuid().ToString('N')).msi"
|
||||||
|
|
||||||
|
Write-Info "Downloading SafeChain Ultimate..."
|
||||||
|
try {
|
||||||
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
|
Invoke-WebRequest -Uri $InstallUrl -OutFile $msiFile -UseBasicParsing
|
||||||
|
$ProgressPreference = 'Continue'
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error-Custom "Failed to download from $InstallUrl : $_"
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Verify SHA256 checksum
|
||||||
|
Write-Info "Verifying checksum..."
|
||||||
|
$actualHash = (Get-FileHash -Path $msiFile -Algorithm SHA256).Hash.ToLower()
|
||||||
|
if ($actualHash -ne $DownloadSha256) {
|
||||||
|
Write-Error-Custom "Checksum verification failed. Expected: $DownloadSha256, Got: $actualHash"
|
||||||
|
}
|
||||||
|
Write-Info "Checksum verified successfully."
|
||||||
|
|
||||||
|
# 3. Install the package with token passed as MSI property
|
||||||
|
Write-Info "Installing SafeChain Ultimate..."
|
||||||
|
$process = Start-Process -FilePath "msiexec" -ArgumentList "/i", "`"$msiFile`"", "/qn", "/norestart", "AIKIDO_TOKEN=$token" -Wait -PassThru
|
||||||
|
if ($process.ExitCode -ne 0) {
|
||||||
|
Write-Error-Custom "MSI installer failed (exit code: $($process.ExitCode))."
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Info "SafeChain Ultimate installed successfully!"
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
# Cleanup
|
||||||
|
if (Test-Path $msiFile) {
|
||||||
|
Remove-Item -Path $msiFile -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run installation
|
||||||
|
try {
|
||||||
|
Install-Endpoint
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error-Custom "Installation failed: $_"
|
||||||
|
}
|
||||||
50
install-scripts/uninstall-endpoint-mac.sh
Normal file
50
install-scripts/uninstall-endpoint-mac.sh
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Uninstalls SafeChain Ultimate endpoint on macOS
|
||||||
|
#
|
||||||
|
# Usage: curl -fsSL <url> | sudo sh
|
||||||
|
|
||||||
|
set -e # Exit on error
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
UNINSTALL_SCRIPT="/Library/Application Support/AikidoSecurity/SafeChainUltimate/scripts/uninstall"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
info() {
|
||||||
|
printf "${GREEN}[INFO]${NC} %s\n" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
printf "${RED}[ERROR]${NC} %s\n" "$1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main uninstallation
|
||||||
|
main() {
|
||||||
|
# Check if we're running on macOS
|
||||||
|
if [ "$(uname -s)" != "Darwin" ]; then
|
||||||
|
error "This script is only supported on macOS."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if we're running as root
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
error "Root privileges required. Please re-run with sudo, e.g.: curl -fsSL <url> | sudo sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the uninstall script exists
|
||||||
|
if [ ! -f "$UNINSTALL_SCRIPT" ]; then
|
||||||
|
error "SafeChain Ultimate does not appear to be installed (uninstall script not found)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Uninstalling SafeChain Ultimate..."
|
||||||
|
"$UNINSTALL_SCRIPT"
|
||||||
|
|
||||||
|
info "SafeChain Ultimate uninstalled successfully!"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
59
install-scripts/uninstall-endpoint-windows.ps1
Normal file
59
install-scripts/uninstall-endpoint-windows.ps1
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Uninstalls SafeChain Ultimate endpoint on Windows
|
||||||
|
#
|
||||||
|
# Usage: iex (iwr '<url>' -UseBasicParsing)
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
$AppName = "SafeChain Ultimate"
|
||||||
|
|
||||||
|
# Helper functions
|
||||||
|
function Write-Info {
|
||||||
|
param([string]$Message)
|
||||||
|
Write-Host "[INFO] $Message" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-Error-Custom {
|
||||||
|
param([string]$Message)
|
||||||
|
Write-Host "[ERROR] $Message" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running as Administrator
|
||||||
|
function Test-Administrator {
|
||||||
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||||
|
$principal = New-Object Security.Principal.WindowsPrincipal($identity)
|
||||||
|
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main uninstallation
|
||||||
|
function Uninstall-Endpoint {
|
||||||
|
# Check if we're running as Administrator
|
||||||
|
if (-not (Test-Administrator)) {
|
||||||
|
Write-Error-Custom "Administrator privileges required. Please run this script in an elevated terminal (Run as Administrator)."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find the installed product
|
||||||
|
Write-Info "Looking for SafeChain Ultimate installation..."
|
||||||
|
$app = Get-WmiObject -Class Win32_Product -Filter "Name='$AppName'"
|
||||||
|
|
||||||
|
if (-not $app) {
|
||||||
|
Write-Error-Custom "SafeChain Ultimate does not appear to be installed."
|
||||||
|
}
|
||||||
|
|
||||||
|
$productCode = $app.IdentifyingNumber
|
||||||
|
|
||||||
|
Write-Info "Uninstalling SafeChain Ultimate..."
|
||||||
|
$process = Start-Process -FilePath "msiexec" -ArgumentList "/x", $productCode, "/qn", "/norestart" -Wait -PassThru
|
||||||
|
if ($process.ExitCode -ne 0) {
|
||||||
|
Write-Error-Custom "Uninstall failed (exit code: $($process.ExitCode))."
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Info "SafeChain Ultimate uninstalled successfully!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run uninstallation
|
||||||
|
try {
|
||||||
|
Uninstall-Endpoint
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error-Custom "Uninstallation failed: $_"
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue