feat: pinned agents and probes only accept peers carrying the operator's proof; the panel ships the signed operator chain with the rosters [CI SKIP]
This commit is contained in:
1 parent
fc2bbdcc6d
commit
9bb6841dce
11 files changed
+129
-12
No files matched your search
@@ -217,4 +217,53 @@ public sealed class TrustTests
|
||||
using HttpResponseMessage anonymous = await _backend.Anonymous.PostAsync("/api/admin/trust", BackendFixture.Json(unsigned));
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, anonymous.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task APinnedAgent_OnlyAcceptsProbesTheOperatorApproved_EvenIfThePanelListsOthers()
|
||||
{
|
||||
Operator op = await OperatorAsync();
|
||||
(string agentSeed, string agentAuth, _) = await CreateSignedCodeAsync(op, role: "agent");
|
||||
await using AgentHarness agent = await AgentHarness.StartAsync(_backend, signed: (agentAuth, agentSeed, op.Genesis));
|
||||
|
||||
// 面板里有一个没有操作员证明的 Probe(相当于面板自己塞进名册的),再有一个操作员批准的
|
||||
using EnrolledProbe plain = await _backend.CreateProbeAsync();
|
||||
(string seed, string auth, _) = await CreateSignedCodeAsync(op, role: "probe");
|
||||
string directory = Path.Combine(Path.GetTempPath(), "moshiro-trust-id-" + Guid.NewGuid().ToString("N"));
|
||||
Result<EnrollmentResult> enrolled = await EnrollAsync(auth, seed, op.Genesis, directory: directory);
|
||||
Assert.True(enrolled.IsSuccess, enrolled.IsSuccess ? "" : enrolled.Error.ToString());
|
||||
using LoadedNodeIdentity approved = LoadedNodeIdentity.Load(directory);
|
||||
|
||||
await BackendFixture.EventuallyAsync(
|
||||
() => Task.FromResult(agent.App.IsPeerKnown(enrolled.Value.NodeId, Convert.ToBase64String(approved.PeerIdentity.PublicKeySpki))),
|
||||
because: "the agent should accept the probe the operator approved");
|
||||
Assert.False(agent.App.IsPeerKnown(plain.ProbeId, Convert.ToBase64String(plain.Identity.PeerIdentity.PublicKeySpki)), "a probe without the operator's proof must not be accepted");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task APinnedProbe_OnlyConnectsToAgentsTheOperatorApproved()
|
||||
{
|
||||
Operator op = await OperatorAsync();
|
||||
(string probeSeed, string probeAuth, _) = await CreateSignedCodeAsync(op, role: "probe");
|
||||
string probeDirectory = Path.Combine(Path.GetTempPath(), "moshiro-trust-id-" + Guid.NewGuid().ToString("N"));
|
||||
Assert.True((await EnrollAsync(probeAuth, probeSeed, op.Genesis, directory: probeDirectory)).IsSuccess);
|
||||
|
||||
(string agentSeed, string agentAuth, _) = await CreateSignedCodeAsync(op, role: "agent");
|
||||
await using AgentHarness agent = await AgentHarness.StartAsync(_backend, signed: (agentAuth, agentSeed, op.Genesis));
|
||||
MemberProofDto? proof = TrustAnchor.Load(agent.DataDirectory, NullNodeLog.Instance).OwnProof;
|
||||
string key = Convert.ToBase64String(agent.TlsPublicKey);
|
||||
|
||||
string configDirectory = Path.Combine(Path.GetTempPath(), "moshiro-probe-cfg-" + Guid.NewGuid().ToString("N"));
|
||||
var directory = new MoShiro.Probe.AgentDirectory(new ConfigStore(configDirectory), configDirectory, NullNodeLog.Instance, TrustAnchor.Load(probeDirectory, NullNodeLog.Instance));
|
||||
directory.Apply(new MoShiro.Protocol.ProbeAgentList
|
||||
{
|
||||
Version = 1,
|
||||
Agents =
|
||||
[
|
||||
new MoShiro.Protocol.AgentEndpoint { AgentId = new NodeId("agt_approved"), Host = "127.0.0.1", TcpPort = 1, PublicKey = key, Proof = proof },
|
||||
new MoShiro.Protocol.AgentEndpoint { AgentId = new NodeId("agt_planted"), Host = "127.0.0.1", TcpPort = 2, PublicKey = key }, // 面板塞进来的:没有证明
|
||||
new MoShiro.Protocol.AgentEndpoint { AgentId = new NodeId("agt_swapped"), Host = "127.0.0.1", TcpPort = 3, PublicKey = Convert.ToBase64String(RandomNumberGenerator.GetBytes(91)), Proof = proof }, // 拿着别人的证明、换了自己的公钥
|
||||
],
|
||||
});
|
||||
Assert.Equal(["agt_approved"], directory.Agents.Select(a => a.AgentId));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user