Check in the keys for both accounts

The keys of the people who deploy are in the repository now: in home/ for
the root user and in admin/ for the Administrator. The resources mirror
both home directories, and the deploy script no longer reads any private
key.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Zebreus 2026-10-25 13:58:05 +01:00
commit a17b2d76dc
14 changed files with 58 additions and 51 deletions

View file

@ -65,7 +65,9 @@ undoes that.
- `home/` - the files that belong in the home directory of the user: `~/.zshrc`, `~/.zshenv` and the keys in
`~/.ssh/authorized_keys` - the one the website logs in with and the ones of the people who deploy. This is where
they are edited.
- `resources/` - the copies the cleanup restores from: the four text files and the files of `home/`.
- `admin/` - the same for the home directory of the Administrator: the keys of the people who deploy. The key of the
website is not among them and never gets administrator rights.
- `resources/` - the copies the cleanup restores from: the files of `home/` and `admin/` and the four text files.
- `scripts/make_files.py` - builds the resources.
- `scripts/deploy.sh` - deploys the cleanup to the server and installs it.
- `scripts/install_restore_task.ps1` - installs the scheduled task.
@ -80,10 +82,10 @@ The resources are built from the website's pages and the files of `home/`:
server/scripts/deploy.sh
The script logs in as `Administrator` - whose shell is a Windows one - copies the scripts and the resources to the
Administrator's home directory and runs the installer there. It logs in with the personal key of the deployer,
`~/.ssh/id_ed25519` by default and `-i` for another one; the key of the website never gets administrator rights, it
only logs in as the root user. It checks the host key against the one the website pins, and checks that the key in
`home/.ssh/authorized_keys` is the one the website uses. `--uninstall` removes the task again.
Administrator's home directory and runs the installer there. It 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.
It checks the host key against the one the website pins, and that the key of the website is the first one in
`home/.ssh/authorized_keys`. `--uninstall` removes the task again.
The installer can also be run by hand, in an elevated PowerShell on the server:

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBTHzLm8QMhHIo7kFAvtAFnqpspeR3L3gM8kLoG1137 lennart@erms

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBTHzLm8QMhHIo7kFAvtAFnqpspeR3L3gM8kLoG1137 lennart@erms

View file

@ -0,0 +1,2 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDweEH8bhZAHVaAedhTVDb2j/oMEn3vm97xCwCw9LC9 root@nowhere.wirs.ing cygwin-2222
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBTHzLm8QMhHIo7kFAvtAFnqpspeR3L3gM8kLoG1137 lennart@erms

View file

@ -0,0 +1,3 @@
# Preset what MSYS2's /etc/profile would otherwise start a helper process for (~90 ms each here).
# TZ has to match the Windows timezone (W. Europe Standard Time).
export LANG=en_US.UTF-8 TZ=Europe/Berlin

View file

@ -0,0 +1,36 @@
# History shared between sessions.
HISTFILE=~/.zsh_history HISTSIZE=10000 SAVEHIST=10000
setopt share_history hist_ignore_dups hist_ignore_space interactive_comments auto_cd
# Completion: menu, case-insensitive, colored. -C skips compaudit, which is slow on
# Windows and meaningless under MSYS2's noacl mounts (rm ~/.zcompdump after adding completions).
autoload -Uz compinit && compinit -C
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
# Emacs keys; Up/Down search history for what is already typed.
bindkey -e
autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search && zle -N down-line-or-beginning-search
bindkey '^[[A' up-line-or-beginning-search '^[OA' up-line-or-beginning-search
bindkey '^[[B' down-line-or-beginning-search '^[OB' down-line-or-beginning-search
# Prompt: user@host:directory, git branch, exit status of the last command if it failed.
# A literal '#' as on Linux: zsh's %# would show '%', since this root is not uid 0.
# The branch is read from .git/HEAD directly: starting git on every prompt is slow on Windows.
precmd() {
local d=$PWD head=
until [[ -e $d/.git || $d == / ]]; do d=${d:h}; done
[[ -f $d/.git/HEAD ]] && read -r head < $d/.git/HEAD
[[ $head == 'ref: '* ]] && git_branch=${head#ref: refs/heads/} || git_branch=${head:0:7}
print -Pn '\e]0;%n@%m: %~\a'
}
setopt prompt_subst
PROMPT='%F{green}%n@%m%f:%F{blue}%~%f${git_branch:+ %5F($git_branch)%f}%(?.. %F{red}[%?]%f)# '
alias ls='ls --color=auto' ll='ls -lah' grep='grep --color=auto'
# Process monitor: htop does not exist for MSYS2 (its /proc only shows MSYS2 processes).
# bottom is a native Windows program; winpty lets it draw in the pty, as Server 2016 has no ConPTY.
alias btm='winpty /ucrt64/bin/btm'

View file

@ -0,0 +1,31 @@
┌─┤ Code of Conduct ├────────────────────────────────────────────────────────────┐
│ Khaos im Kiez ist eine Veranstaltung des Chaos Computer Club Berlin e.V. │
│ (CCCB). Damit sich alle wohlfühlen, gelten diese Regeln für alle │
│ Teilnehmenden, Vortragenden und Helfenden. │
│ │
│ > Sei nett zueinander. Geh respektvoll und freundlich miteinander um, auch │
│ wenn du anderer Meinung bist. │
│ > Keine Diskriminierung. Rassismus, Sexismus, Queerfeindlichkeit, Ableismus │
│ und andere menschenverachtende Haltungen haben hier keinen Platz. │
│ > Keine Belästigung. Dazu gehören Beleidigungen, Bedrohungen, Stalking, │
│ unerwünschte körperliche Berührungen und unerwünschte sexuelle │
│ Aufmerksamkeit. Ein Nein ist ein Nein. │
│ > Frag vor dem Fotografieren. Fotos, Video- und Tonaufnahmen von Personen nur │
│ mit deren Einverständnis. Das gilt auch für Talks und Workshops. │
│ > Achte auf Geräte und Eigentum. Fass fremde Geräte nicht ohne Erlaubnis an. │
│ Geh pfleglich mit den Räumen und dem Inventar um. │
│ > Sei neugierig, nicht übergriffig. Chaos ja, Grenzenüberschreitungen nein. │
│ │
│ Hausrecht: Die Orga hat Hausrecht. Bei Verstößen gegen diese Regeln kann sie │
│ Verwarnungen aussprechen, Personen der Veranstaltung verweisen oder ein │
│ Hausverbot erteilen. Den Anweisungen der Orga ist Folge zu leisten. │
│ │
│ Probleme? Wenn dir etwas passiert oder du etwas beobachtest, sprich eine │
│ Person aus der Orga an oder schreib an aprl [at] berlin [dot] ccc [dot] de. │
│ Hinweise werden vertraulich behandelt. │
└────────────────────────────────────────────────────────────────────────────────┘
──────────────────────────────────────────────────────────────────────────────────
]8;;https://berlin.ccc.de/kik/\Startseite]8;;\ · ]8;;https://berlin.ccc.de/page/impressum/\Impressum]8;;\

View file

@ -0,0 +1,30 @@
┌─┤ Code of Conduct ├────────────────────────────────────────────────────────────┐
│ Khaos im Kiez is an event of the Chaos Computer Club Berlin e.V. (CCCB). To │
│ make everyone feel comfortable, these rules apply to all attendees, speakers │
│ and helpers. │
│ │
│ > Be nice to each other. Treat each other respectfully and kindly, even when │
│ you disagree. │
│ > No discrimination. Racism, sexism, queerphobia, ableism and other hateful │
│ attitudes have no place here. │
│ > No harassment. This includes insults, threats, stalking, unwanted physical │
│ contact and unwanted sexual attention. No means no. │
│ > Ask before taking pictures. Photos, video and audio recordings of people │
│ only with their consent. This also applies to talks and workshops. │
│ > Respect devices and property. Do not touch other people's devices without │
│ permission. Treat the rooms and furniture with care. │
│ > Be curious, not intrusive. Chaos yes, crossing boundaries no. │
│ │
│ House rules: The organizers have the right to exclude people from the premises │
│ (Hausrecht). In case of violations they may issue warnings, ask people to │
│ leave, or ban them from the event. Follow the organizers' instructions. │
│ │
│ Problems? If something happens to you or you notice something, talk to a │
│ member of the organizing team or write to aprl [at] berlin [dot] ccc [dot] de. │
│ Reports are treated confidentially. │
└────────────────────────────────────────────────────────────────────────────────┘
──────────────────────────────────────────────────────────────────────────────────
]8;;https://berlin.ccc.de/kik/en.html\Home]8;;\ · ]8;;https://berlin.ccc.de/page/impressum/\Legal notice]8;;\

View file

@ -0,0 +1,79 @@
KHAOS IM KIEZ
CCC Berlin · 28. – 29.11.2026
──────────────────────────────────────────────────────────────────────────────────
]8;;https://berlin.ccc.de/kik/#infos\[1] Infos]8;;\ ]8;;https://berlin.ccc.de/kik/#mitmachen\[2] Mitmachen]8;;\ ]8;;https://berlin.ccc.de/kik/#anfahrt\[3] Anfahrt]8;;\
──────────────────────────────────────────────────────────────────────────────────
┌─┤ 1 Infos ├────────────────────────────────────────────────────────────────────┐
│ Khaos im Kiez ist ein kleines Chaos-Event, back to the roots: inspiriert von │
│ anderen kleinen Chaos-Events. Ein Wochenende zum Chillen und um die Seite von │
│ Chaos-Events zu erleben, für die bei größeren Events oft keine Zeit mehr │
│ bleibt. │
│ │
│ Du kannst einen Talk oder Workshop halten, an deinen Projekten schrauben, │
│ gemeinsam hacken, löten, basteln oder einfach vorbeikommen, zuhören und Leute │
│ kennenlernen. Alle sind willkommen, die Lust auf $Dinge, Neugier und Chaos │
│ mitbringen. │
│ │
│ Was : Khaos im Kiez (KiK) │
│ Wann : Sa 28.11. – So 29.11.2026, 11:00 – 23:59 │
│ Wo : Marienstraße 11, 10117 Berlin │
│ Wer : Chaos Computer Club Berlin │
│ Preis : 0,00 € (Ticket trotzdem nötig, ~50 Plätze) │
│ Fahrplan : ]8;;https://cfp.berlin.ccc.de\cfp.berlin.ccc.de]8;;\ │
│ Essen : Ewiges Frühstück, vegan │
│ Barrierefrei : Nicht barrierefrei. │
│ Regeln : ]8;;https://berlin.ccc.de/kik/coc.html\Code of Conduct]8;;\ │
└────────────────────────────────────────────────────────────────────────────────┘
┌─┤ 2 Mitmachen ├────────────────────────────────────────────────────────────────┐
│ Ticket: Anmeldung über den Ticketshop. Das Ticket ist kostenlos, aber die │
│ Plätze sind begrenzt. │
│ │
│ ]8;;https://tickets.berlin.ccc.de/cccb/kik-v0.1/\[ Ticket sichern ]]8;;\ │
│ │
│ Talks & Workshops: Reiche deinen Beitrag im Call for Participation ein und │
│ schau dir später den Fahrplan an. │
│ │
│ ]8;;https://cfp.berlin.ccc.de/kik-v01/cfp\[ Talk einreichen ]]8;;\ ]8;;https://cfp.berlin.ccc.de/kik-v01/schedule\[ Fahrplan ]]8;;\ │
│ │
│ Sonstiges: Du willst anders helfen oder hast Fragen? Schreib an aprl [at] │
│ berlin [dot] ccc [dot] de. │
└────────────────────────────────────────────────────────────────────────────────┘
┌─┤ 3 Anfahrt ├──────────────────────────────────────────────────────────────────┐
│ Adresse : Clubräume im Hinterhof der Marienstraße 11, 10117 Berlin │
│ Koordinaten : 52,52194° N, 13,38261° O │
│ Fahrrad : Im Innenhof gibt es eine begrenzte Zahl an Fahrradständern. Auf │
│ dem Weg liegen viele Fahrradstraßen, nutz die am besten, z. B. │
│ mit ]8;;http://www.bbbike.de/\BBBike.de]8;;\. │
│ ÖPNV : Der Club liegt direkt beim S+U-Bahnhof Friedrichstraße (auch │
│ Regionalbahnen). Vom oberirdischen S-Bahn-Steig (S3/S5/S7) │
│ nimmst du den Ausgang Schiffbauerdamm und gehst unter der │
│ Bahnbrücke über die Spree. Über die Albrechtstraße kommst du │
│ zur Marienstraße. │
│ Fernverkehr : Aussteigen in Berlin Hauptbahnhof, dann mit S-Bahn oder │
│ Regionalbahn Richtung Osten eine Station bis Friedrichstraße. │
│ Bahnhof Richtung Spree verlassen, über die Fußgängerbrücke und │
│ der Albrechtstraße bis zur Stichstraße Marienstraße folgen. │
│ Flugzeug : BER: Airport Express (RE7, RB14) oder S9 bis Friedrichstraße, │
│ alternativ FEX bis Hauptbahnhof (dann wie Fernverkehr). │
│ Achtung: Terminal 5 (früher SXF) ist nicht mit dem Rest des BER │
│ verbunden, dort fährt nur die S9. Flugplatz Strausberg (EDAY): │
│ S7 direkt bis Friedrichstraße. │
│ Auto : Zufahrt von Hauptbahnhof oder Brandenburger Tor über die │
│ Luisenstraße. Von der Friedrichstraße entweder über │
│ Schiffbauerdamm und Albrechtstraße (Außengastronomie und │
│ Kopfsteinpflaster) oder über Reinhardstraße und Luisenstraße │
│ (die Albrechtstraße ist nur in Gegenrichtung befahrbar). │
│ Parken : Achtung: Es gibt kaum Parkplätze, und die Marienstraße und alle │
│ umliegenden Straßen sind parkraumbewirtschaftet. │
│ │
│ ]8;;https://www.openstreetmap.org/node/3872556357#map=20/52.5217003/13.3828041&layers=H\[ Karte (OpenStreetMap) ]]8;;\ │
└────────────────────────────────────────────────────────────────────────────────┘
──────────────────────────────────────────────────────────────────────────────────
]8;;https://berlin.ccc.de/page/impressum/\Impressum]8;;\ · ]8;;https://berlin.ccc.de/\CCC Berlin]8;;\

View file

@ -0,0 +1,77 @@
KHAOS IM KIEZ
CCC Berlin · 2026-11-28 – 2026-11-29
──────────────────────────────────────────────────────────────────────────────────
]8;;https://berlin.ccc.de/kik/en.html#infos\[1] Info]8;;\ ]8;;https://berlin.ccc.de/kik/en.html#join\[2] Join in]8;;\ ]8;;https://berlin.ccc.de/kik/en.html#getting-here\[3] Getting here]8;;\
──────────────────────────────────────────────────────────────────────────────────
┌─┤ 1 Info ├─────────────────────────────────────────────────────────────────────┐
│ Khaos im Kiez is a small chaos event, back to the roots: inspired by other │
│ small chaos events. A weekend to chill and to experience the side of chaos │
│ events that often gets no time at larger events. │
│ │
│ Give a talk or workshop, work on your projects, hack together, solder, tinker, │
│ or simply drop by, listen and meet people. Everyone who brings a love of │
│ $things, curiosity and a bit of chaos is welcome. │
│ │
│ What : Khaos im Kiez (KiK) │
│ When : Sat 2026-11-28 – Sun 2026-11-29, 11:00 – 23:59 │
│ Where : Marienstraße 11, 10117 Berlin, Germany │
│ Who : Chaos Computer Club Berlin │
│ Price : €0.00 (ticket still required, ~50 seats) │
│ Schedule : ]8;;https://cfp.berlin.ccc.de\cfp.berlin.ccc.de]8;;\ │
│ Food : Eternal breakfast, vegan │
│ Accessibility : Not accessible. │
│ Rules : ]8;;https://berlin.ccc.de/kik/coc-en.html\Code of Conduct]8;;\ │
└────────────────────────────────────────────────────────────────────────────────┘
┌─┤ 2 Join in ├──────────────────────────────────────────────────────────────────┐
│ Ticket: Register via the ticket shop. The ticket is free, but seats are │
│ limited. │
│ │
│ ]8;;https://tickets.berlin.ccc.de/cccb/kik-v0.1/\[ Get ticket ]]8;;\ │
│ │
│ Talks & workshops: Submit your proposal via the call for participation and │
│ check the schedule later. │
│ │
│ ]8;;https://cfp.berlin.ccc.de/kik-v01/cfp\[ Submit a talk ]]8;;\ ]8;;https://cfp.berlin.ccc.de/kik-v01/schedule\[ Schedule ]]8;;\ │
│ │
│ Other: Want to help otherwise or have questions? Write to aprl [at] berlin │
│ [dot] ccc [dot] de. │
└────────────────────────────────────────────────────────────────────────────────┘
┌─┤ 3 Getting here ├─────────────────────────────────────────────────────────────┐
│ Address : Club rooms in the back yard of Marienstraße 11, 10117 Berlin │
│ Coordinates : 52.52194° N, 13.38261° E │
│ Bicycle : A limited number of bike racks are in the courtyard. Many │
│ bicycle streets lead there, preferably use those, e.g. with │
│ ]8;;http://www.bbbike.de/\BBBike.de]8;;\. │
│ Local transit : The club is right next to S+U Friedrichstraße (regional trains │
│ stop there too). From the elevated S-Bahn platform (S3/S5/S7) │
│ take the Schiffbauerdamm exit and walk across the Spree │
│ beneath the railway bridge. Albrechtstraße leads to │
│ Marienstraße. │
│ Long distance : Get off at Berlin Hauptbahnhof, then take any S-Bahn or │
│ regional train eastbound one stop to Friedrichstraße. Leave │
│ the station towards the Spree, cross the footbridge and follow │
│ Albrechtstraße to the dead-end Marienstraße. │
│ Air : BER: Airport Express (RE7, RB14) or S9 to Friedrichstraße, or │
│ FEX to Hauptbahnhof (then as above). Note: Terminal 5 │
│ (formerly SXF) is not connected to the rest of BER, only the │
│ S9 runs there. Strausberg airfield (EDAY): S7 direct to │
│ Friedrichstraße. │
│ Car : Access from Hauptbahnhof or Brandenburger Tor via │
│ Luisenstraße. From Friedrichstraße either via Schiffbauerdamm │
│ and Albrechtstraße (outdoor seating and cobblestones) or via │
│ Reinhardstraße and Luisenstraße (Albrechtstraße is one-way the │
│ other direction). │
│ Parking : Warning: parking is scarce, and Marienstraße and all │
│ surrounding streets are subject to paid parking zones. │
│ │
│ ]8;;https://www.openstreetmap.org/node/3872556357#map=20/52.5217003/13.3828041&layers=H\[ Map (OpenStreetMap) ]]8;;\ │
└────────────────────────────────────────────────────────────────────────────────┘
──────────────────────────────────────────────────────────────────────────────────
]8;;https://berlin.ccc.de/page/impressum/\Legal notice]8;;\ · ]8;;https://berlin.ccc.de/\CCC Berlin]8;;\

View file

@ -6,13 +6,13 @@
# 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, by default ~/.ssh/id_ed25519. The key of the
# website never gets administrator rights: it only logs in as the root user.
# 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="$HOME/.ssh/id_ed25519"
KEYFILE=''
UNINSTALL=0
while [ $# -gt 0 ]; do
@ -30,11 +30,6 @@ remote='C:\Users\Administrator\kik' # where the installer is put, in the home
remotePath='/c/Users\Administrator\kik' # the same place, as the file transfer sees it
temporary=()
if [ ! -f "$KEYFILE" ]; then
echo "no key file for the login as $USER: $KEYFILE" >&2
exit 1
fi
# 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)
@ -47,19 +42,15 @@ if [ "$actual" != "$expected" ]; then
exit 1
fi
# The site logs in with the key in the authorized_keys of the user on the box, so the two have to be the same.
site=$(mktemp)
chmod 600 "$site"
temporary+=("$site")
boring=$(sed -n "s/.*const boringData = '\([^']*\)'.*/\1/p" "$repo/src/scripts/terminal.ts")
printf '%s' "$boring" | base64 -d | tr 'A-Za-z' 'N-ZA-Mn-za-m' > "$site"
public=$(ssh-keygen -y -f "$site" | awk 'NF {print $1" "$2}')
if ! awk 'NF {print $1" "$2}' "$server/resources/.ssh/authorized_keys" | grep -qxF "$public"; then
echo "the key in server/resources/.ssh/authorized_keys is not the one the website uses" >&2
# 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=(-i "$KEYFILE" -o "UserKnownHostsFile=$known" -o StrictHostKeyChecking=yes)
options=(-o "UserKnownHostsFile=$known" -o StrictHostKeyChecking=yes)
if [ -n "$KEYFILE" ]; then options+=(-i "$KEYFILE"); fi
ssh=(ssh "${options[@]}" "$USER@$HOST")
scp=(scp "${options[@]}")
@ -68,13 +59,9 @@ if [ "$UNINSTALL" = 1 ]; then
exit
fi
# The installer looks for the resources next to itself, so both directories go to the server.
"${ssh[@]}" "if not exist $remote mkdir $remote"
# 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"
# The Administrator logs in with the key of the deployer, so that it is there after every deployment.
keyline=$(ssh-keygen -y -f "$KEYFILE")
blob=$(echo "$keyline" | awk 'NF {print $2}')
"${ssh[@]}" "if not exist C:\\Users\\Administrator\\.ssh mkdir C:\\Users\\Administrator\\.ssh"
"${ssh[@]}" "findstr /c:\"$blob\" C:\\Users\\Administrator\\.ssh\\authorized_keys >nul 2>&1 || echo $keyline >> C:\\Users\\Administrator\\.ssh\\authorized_keys"

View file

@ -25,7 +25,7 @@ $restoreScript = @'
# server's root user can neither stop it nor change the copies it restores from.
param([string]$HomeDir = 'C:\msys2\home\root')
$log = Join-Path $PSScriptRoot 'restore.log'
$copies = Join-Path $PSScriptRoot 'files'
$copies = Join-Path $PSScriptRoot 'files\home'
# The account of the shell server's root user, whose id the files in its home directory belong to.
$passwd = Get-Content 'C:\msys2\etc\passwd' -ErrorAction SilentlyContinue | Where-Object { $_ -like 'root:*' }
@ -51,10 +51,10 @@ function Remove-Anything($path) {
# the key of the website is put back.
function Restore-Keys($target, $source) {
$required = @(Get-Content -LiteralPath $source | Where-Object { $_.Trim() })
$blob = ($required[0] -split '\s+')[1]
$blobs = $required | ForEach-Object { ($_ -split '\s+')[1] }
$keys = @()
if (Test-Path -LiteralPath $target) {
$keys = @(Get-Content -LiteralPath $target | Where-Object { $_.Trim() -and ($_ -split '\s+')[1] -ne $blob })
$keys = @(Get-Content -LiteralPath $target | Where-Object { $_.Trim() -and $blobs -notcontains ($_ -split '\s+')[1] })
}
[IO.File]::WriteAllText($target, (($keys + $required) -join "`n") + "`n")
}
@ -127,7 +127,7 @@ if ($Uninstall) {
}
$resources = Join-Path $PSScriptRoot '..\resources'
if (-not (Get-ChildItem -LiteralPath $resources -File -Force)) { throw "No files in $resources." }
if (-not (Get-ChildItem -LiteralPath $resources -Recurse -File -Force)) { throw "No files in $resources." }
# The root user may have prepared the directory or the file names, so nothing that looks like a link is used.
$prepared = Get-Item -LiteralPath $installDir -Force -ErrorAction SilentlyContinue
@ -152,6 +152,16 @@ foreach ($item in Get-ChildItem -LiteralPath $copiesDir -Recurse -Force) {
Remove-Item -LiteralPath $copiesDir -Recurse -Force
New-Item -ItemType Directory -Force -Path $copiesDir | Out-Null
Copy-Item -Path (Join-Path $resources '*') -Destination $copiesDir -Recurse -Force
# The Administrator logs in with the key of the people who deploy, which is in the resources. The keys that are
# already there stay.
$adminKeys = 'C:\Users\Administrator\.ssh\authorized_keys'
$required = @(Get-Content -LiteralPath (Join-Path $resources 'admin\.ssh\authorized_keys') | Where-Object { $_.Trim() })
$keys = @()
if (Test-Path -LiteralPath $adminKeys) { $keys = @(Get-Content -LiteralPath $adminKeys | Where-Object { $_.Trim() }) }
if (-not ($keys | Where-Object { ($_ -split '\s+')[1] -eq ($required[0] -split '\s+')[1] })) {
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $adminKeys) | Out-Null
[IO.File]::WriteAllText($adminKeys, (($keys + $required) -join "`n") + "`n")
}
[IO.File]::WriteAllText((Join-Path $installDir 'restore.ps1'), $restoreScript)
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$installDir\restore.ps1`" -HomeDir `"$HomeDir`""

View file

@ -1,6 +1,6 @@
# Builds the files for the home directory of the shell server's root user in ../resources: README, README.en,
# CODE_OF_CONDUCT and CODE_OF_CONDUCT.en as the website's pages in terminal text with escape sequences, and the
# files of ../home, which are copied as they are.
# Builds the files for the home directories of the shell server in ../resources: the home of the root user with
# README, README.en, CODE_OF_CONDUCT and CODE_OF_CONDUCT.en as the website's pages in terminal text with escape
# sequences, and the files of ../home and ../admin, which are copied as they are.
# Usage: python3 server/scripts/make_files.py
import pathlib
import shutil
@ -332,16 +332,18 @@ COC_EN = {
}
out = pathlib.Path(__file__).parent.parent / 'resources'
out.mkdir(exist_ok=True)
(out / 'home').mkdir(parents=True, exist_ok=True)
for name, text in [('README', readme(DE)), ('README.en', readme(EN)),
('CODE_OF_CONDUCT', code_of_conduct(COC_DE)), ('CODE_OF_CONDUCT.en', code_of_conduct(COC_EN))]:
(out / name).write_text(text, encoding='utf-8')
# The files for the home directory are not generated, they are copied from ../home, where they are edited.
home = pathlib.Path(__file__).parent.parent / 'home'
for path in home.rglob('*'):
target = out / path.relative_to(home)
if path.is_dir():
target.mkdir(parents=True, exist_ok=True)
else:
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(path, target)
(out / 'home' / name).write_text(text, encoding='utf-8')
# The files of the home directories are not generated, they are copied from ../home and ../admin, where they are
# edited.
for source in 'home', 'admin':
root = pathlib.Path(__file__).parent.parent / source
for path in root.rglob('*'):
target = out / source / path.relative_to(root)
if path.is_dir():
target.mkdir(parents=True, exist_ok=True)
else:
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(path, target)

View file

@ -1,15 +1,19 @@
@echo off
REM Puts the SSH access back that a deleted home directory took with it: the key the website logs in with, in the
REM home of the root user. Run it as Administrator on the box, for example over RDP. The cleanup job puts the key
REM back by itself from then on.
REM home of the root user, and the key of the deployer in the home of the Administrator. Run it as Administrator on
REM the box, for example over RDP. The cleanup job puts the key of the website back by itself from then on.
setlocal EnableDelayedExpansion
set KEY=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDweEH8bhZAHVaAedhTVDb2j/oMEn3vm97xCwCw9LC9 root@nowhere.wirs.ing cygwin-2222
set OWN=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBTHzLm8QMhHIo7kFAvtAFnqpspeR3L3gM8kLoG1137 lennart@erms
set BLOB=AAAAC3NzaC1lZDI1NTE5AAAAIIBTHzLm8QMhHIo7kFAvtAFnqpspeR3L3gM8kLoG1137
if not exist C:\msys2\home\root\.ssh mkdir C:\msys2\home\root\.ssh
> C:\msys2\home\root\.ssh\authorized_keys echo %KEY%
echo %OWN% >> C:\msys2\home\root\.ssh\authorized_keys
if not exist C:\Users\Administrator\.ssh mkdir C:\Users\Administrator\.ssh
findstr /c:"%BLOB%" C:\Users\Administrator\.ssh\authorized_keys >nul 2>&1 || echo %OWN% >> C:\Users\Administrator\.ssh\authorized_keys
REM The user owns their .ssh, so that they can add keys of their own.
for /f "tokens=5" %%i in ('findstr /b "root:" C:\msys2\etc\passwd') do set SID=%%i
set SID=!SID:*,=!