using ClawdDotNet.Core.Instances; using Shouldly; namespace ClawdDotNet.Core.Tests.Instances; /// /// The proof that a licensed instance manager started the instance (#535). /// /// The hole this closes. With E-M3 a managed instance no longer checks the license /// itself — the manager did it centrally. What it recognized "managed" by was /// the switch --managed, and a switch is no recognition. /// /// The point is not to fend off someone who brings tools: the key /// is in the executable. The point is that the ordinary way around the license /// is closed. /// 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(); } /// /// The case that was the occasion in the first place: --managed without a signature. /// [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(); } /// /// A made-up signature does not hold — even if the structure is right. /// [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(); } /// /// The check is against the directory the instance actually runs in. /// /// Otherwise one would sign the argument instead of the thing: a signature for /// Alpha would let Beta start by presenting Alpha during the check. /// [Fact] public void Eine_Unterschrift_gilt_nur_fuer_ihre_eigene_Instanz() { var token = ManagerHandshake.Sign(Instanz); ManagerHandshake.Verify(Andere, token).ShouldBeFalse(); } /// /// Expired is expired — otherwise someone would keep a signature and start /// an instance without a license with it next week. /// [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."); } /// /// Fiddling with the expiry time does not help: it goes into the signature. /// [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(); } /// /// The same path in a different spelling must yield the same signature — otherwise /// the handshake fails because one wrote one slash more. /// [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(); } }