using ClawdDotNet.Core.Instances; using Shouldly; namespace ClawdDotNet.Core.Tests.Instances; /// /// Der Nachweis, dass ein lizenzierter Instanzmanager die Instanz gestartet hat (#535). /// /// Das Loch, das hier zugeht. Mit E-M3 prüft eine geführte Instanz die Lizenz /// nicht mehr selbst — der Manager hat es zentral getan. Woran sie „geführt" erkannte, war /// der Schalter --managed, und ein Schalter ist keine Erkennung. /// /// Es geht nicht darum, jemanden abzuwehren, der Werkzeuge mitbringt: Der Schlüssel /// steht in der Programmdatei. Es geht darum, dass der gewöhnliche Weg an der Lizenz /// vorbei verschlossen ist. /// public sealed class ManagerHandshakeTests { private const string Instanz = "/daten/Instances/Alpha"; private const string Andere = "/daten/Instances/Beta"; [Fact] public void Eine_frische_Unterschrift_traegt() { var token = ManagerHandshake.Sign(Instanz); ManagerHandshake.Verify(Instanz, token).ShouldBeTrue(); } /// /// Der Fall, der überhaupt der Anlass war: --managed ohne Unterschrift. /// [Theory] [InlineData(null)] [InlineData("")] [InlineData(" ")] [InlineData("--managed")] [InlineData("v1")] [InlineData("v1.999.")] [InlineData("v2.99999999999.abcdef")] [InlineData("v1.keinezahl.abcdef")] public void Ohne_brauchbare_Unterschrift_gilt_die_Instanz_als_ungefuehrt(string? token) { ManagerHandshake.Verify(Instanz, token).ShouldBeFalse(); } /// /// Eine erfundene Unterschrift trägt nicht — auch wenn der Aufbau stimmt. /// [Fact] public void Eine_erfundene_Unterschrift_traegt_nicht() { var ablauf = DateTimeOffset.UtcNow.AddMinutes(5).ToUnixTimeSeconds(); ManagerHandshake.Verify(Instanz, $"v1.{ablauf}.{new string('a', 64)}") .ShouldBeFalse(); } /// /// Geprüft wird gegen das Verzeichnis, in dem die Instanz tatsächlich läuft. /// /// Sonst unterschriebe man das Argument statt der Sache: Eine Unterschrift für /// Alpha ließe Beta starten, indem man beim Prüfen Alpha vorzeigt. /// [Fact] public void Eine_Unterschrift_gilt_nur_fuer_ihre_eigene_Instanz() { var token = ManagerHandshake.Sign(Instanz); ManagerHandshake.Verify(Andere, token).ShouldBeFalse(); } /// /// Abgelaufen ist abgelaufen — sonst hübe jemand eine Unterschrift auf und startete /// damit nächste Woche eine Instanz ohne Lizenz. /// [Fact] public void Eine_abgelaufene_Unterschrift_traegt_nicht() { var vorhin = DateTimeOffset.UtcNow.AddHours(-1); var token = ManagerHandshake.Sign(Instanz, vorhin); ManagerHandshake.Verify(Instanz, token, vorhin).ShouldBeTrue("Damals galt sie."); ManagerHandshake.Verify(Instanz, token).ShouldBeFalse("Jetzt nicht mehr."); } /// /// Am Ablaufzeitpunkt herumzudrehen hilft nicht: Er geht in die Unterschrift ein. /// [Fact] public void Ein_verlaengerter_Ablauf_macht_die_Unterschrift_ungueltig() { var token = ManagerHandshake.Sign(Instanz); var teile = token.Split('.'); var spaeter = DateTimeOffset.UtcNow.AddYears(1).ToUnixTimeSeconds(); ManagerHandshake.Verify(Instanz, $"v1.{spaeter}.{teile[2]}").ShouldBeFalse(); } /// /// Derselbe Pfad in anderer Schreibweise muss dieselbe Unterschrift ergeben — sonst /// scheitert der Handschlag daran, dass einer einen Schrägstrich mehr geschrieben hat. /// [Fact] public void Schreibweisen_desselben_Pfades_ergeben_dieselbe_Unterschrift() { var basis = Path.Combine(Path.GetTempPath(), "clawd-handschlag"); var token = ManagerHandshake.Sign(basis); ManagerHandshake.Verify(basis + Path.DirectorySeparatorChar, token).ShouldBeTrue(); ManagerHandshake.Verify(Path.Combine(basis, "."), token).ShouldBeTrue(); } }