#!/usr/bin/env bash # Deploys the cleanup job to the shell server and installs it there. # # server/scripts/deploy.sh [-i KEYFILE] [-h HOST] [--uninstall] # # The job runs on the box as SYSTEM, never as the root user. The Administrator account sets it up; its shell is a # Windows one, so the commands we run there are Windows commands. # # The Administrator logs in with the personal key of the deployer, from the agent or from -i. The key of the website # never gets administrator rights: it only logs in as the root user. set -euo pipefail HOST=nowhere.wirs.ing USER=Administrator KEYFILE='' UNINSTALL=0 while [ $# -gt 0 ]; do case $1 in -i) KEYFILE=$2; shift 2 ;; -h) HOST=$2; shift 2 ;; --uninstall) UNINSTALL=1; shift ;; *) echo "usage: $(basename "$0") [-i KEYFILE] [-h HOST] [--uninstall]" >&2; exit 2 ;; esac done repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) server="$repo/server" remote='C:\Users\Administrator\kik' # where the installer is put, in the home of the Administrator remotePath='/c/Users\Administrator\kik' # the same place, as the file transfer sees it temporary=() # The host key is the one the website pins, so that the deployment cannot be intercepted. expected=$(sed -n "s/.*const HOST_KEY = '\([^']*\)'.*/\1/p" "$repo/src/scripts/terminal.ts") known=$(mktemp) temporary+=("$known") trap 'rm -f "${temporary[@]}"' EXIT ssh-keyscan -t ed25519 "$HOST" > "$known" 2>/dev/null actual=$(ssh-keygen -lf "$known" | awk '{print $2}') if [ "$actual" != "$expected" ]; then echo "the host key of $HOST is $actual, but $expected is expected" >&2 exit 1 fi # The site logs in with the first key in the authorized_keys of the user on the box, so it has to be the right one. sitekey=$(ssh-keygen -lf "$server/resources/home/.ssh/authorized_keys" | awk 'NR==1 {print $2}') if [ "$sitekey" != 'SHA256:KUEv4d4+75h41l0OGTWCA2FbtEOQZ047ujkeh+kkFW0' ]; then echo "the key of the website is not the first one in server/resources/home/.ssh/authorized_keys" >&2 exit 1 fi options=(-o "UserKnownHostsFile=$known" -o StrictHostKeyChecking=yes) if [ -n "$KEYFILE" ]; then options+=(-i "$KEYFILE"); fi ssh=(ssh "${options[@]}" "$USER@$HOST") scp=(scp "${options[@]}") if [ "$UNINSTALL" = 1 ]; then "${ssh[@]}" "if exist $remote\\scripts\\install_restore_task.ps1 (powershell -NoProfile -ExecutionPolicy Bypass -File $remote\\scripts\\install_restore_task.ps1 -Uninstall) else (echo Nothing is installed.)" exit fi # The installer looks for the resources next to itself, so both directories go to the server. What was there # before is removed, so that files that are gone from the repository do not stay on the box. "${ssh[@]}" "if exist $remote rmdir /s /q $remote" "${ssh[@]}" "mkdir $remote" "${scp[@]}" -r "$server/scripts" "$server/resources" "$USER@$HOST:$remotePath/" "${ssh[@]}" "powershell -NoProfile -ExecutionPolicy Bypass -File $remote\\scripts\\install_restore_task.ps1"