toContain('CONTRACT=3') ->and(installAgent())->toContain('install-server-terminal)'); }); it('gibt dem Dienstkonto KEINEN sudo-Weg, sich selbst einen Root-Schluessel einzutragen', function () { $script = installAgent(); // Der sudoers-Block nennt genau die Schritte, die das Dienstkonto anstossen // darf. `install-server-terminal` schreibt nach /root/.ssh/authorized_keys; // stuende er dort, koennte eine uebernommene Anwendung sich jederzeit // selbst root geben — Kennung neu erzeugen, Schritt anstossen, fertig. $sudoers = str($script)->after('/etc/sudoers.d/clupilot-host-step <before('EOF')->toString(); expect($sudoers)->toContain('ensure-rsync') ->and($sudoers)->toContain('apply-proxy-hosts') ->and($sudoers)->not->toContain('install-server-terminal'); }); it('nimmt genau eine ssh-ed25519-Zeile an und nichts sonst', function () { $script = installAgent(); // Die beiden Haelften der Pruefung: „genau eine Zeile" und „sieht aus wie // ein Schluessel". Ohne die erste waere ein Zeilenumbruch im Wert ein // zweiter Schluessel; ohne die zweite genuegte irgendein Text. expect($script)->toContain('-eq 1 ]] \\') ->and($script)->toContain('^ssh-ed25519\ [A-Za-z0-9+/]+=*'); }); it('schreibt die Optionsliste selbst, statt sie sich reichen zu lassen', function () { // `from` bindet den Schluessel an das Container-Netz, `restrict` nimmt ihm // alles ausser einer Sitzung, `pty` gibt das eine zurueck, ohne das ein // Terminal keines ist. Kaeme diese Liste aus der Anwendung, waere aus „die // Anwendung nennt ihren Schluessel" ein „die Anwendung schreibt in // authorized_keys" geworden. expect(installAgent())->toContain('from="%s",restrict,pty %s'); }); it('bildet den Fingerabdruck in CluPilots Form, nicht in der von OpenSSH', function () { $script = installAgent(); // Gehasht wird die Zeichenkette " " — siehe // fingerprints() in docker/terminal/bridge.py. `ssh-keygen -lf` gaebe den // bekannten OpenSSH-Fingerabdruck und damit bei JEDEM Verbindungsversuch // eine Abweichung. expect($script)->toContain("printf '%s %s'") ->and($script)->toContain('openssl dgst -sha256 -binary') ->and($script)->not->toContain('ssh-keygen -lf'); }); it('haelt Adresse und Fingerabdruck dort fest, wo die Anwendung sie liest', function () { expect(installAgent())->toContain('storage/app/deploy/server-terminal.json') ->and(installAgent())->toContain('"installed_at"'); });