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 InstanceDir = "/daten/Instances/Alpha"; private const string OtherDir = "/daten/Instances/Beta"; [Fact] public void A_fresh_signature_holds() { var token = ManagerHandshake.Sign(InstanceDir); ManagerHandshake.Verify(InstanceDir, 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 Without_a_usable_signature_the_instance_counts_as_unmanaged(string? token) { ManagerHandshake.Verify(InstanceDir, token).ShouldBeFalse(); } /// /// A made-up signature does not hold — even if the structure is right. /// [Fact] public void A_forged_signature_does_not_hold() { var expiry = DateTimeOffset.UtcNow.AddMinutes(5).ToUnixTimeSeconds(); ManagerHandshake.Verify(InstanceDir, $"v1.{expiry}.{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 A_signature_is_only_valid_for_its_own_instance() { var token = ManagerHandshake.Sign(InstanceDir); ManagerHandshake.Verify(OtherDir, 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 An_expired_signature_does_not_hold() { var earlier = DateTimeOffset.UtcNow.AddHours(-1); var token = ManagerHandshake.Sign(InstanceDir, earlier); ManagerHandshake.Verify(InstanceDir, token, earlier).ShouldBeTrue("Damals galt sie."); ManagerHandshake.Verify(InstanceDir, token).ShouldBeFalse("Jetzt nicht mehr."); } /// /// Fiddling with the expiry time does not help: it goes into the signature. /// [Fact] public void An_extended_expiry_invalidates_the_signature() { var token = ManagerHandshake.Sign(InstanceDir); var parts = token.Split('.'); var later = DateTimeOffset.UtcNow.AddYears(1).ToUnixTimeSeconds(); ManagerHandshake.Verify(InstanceDir, $"v1.{later}.{parts[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 Spellings_of_the_same_path_give_the_same_signature() { 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(); } }