Skip to content

Commit 5660e03

Browse files
committed
add auth to in-memory coordinator
1 parent 4aaa0e2 commit 5660e03

File tree

4 files changed

+85
-2
lines changed

4 files changed

+85
-2
lines changed

tailnet/coordinator.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,10 @@ func (c *core) handleReadyForHandshakeLocked(src *peer, rfhs []*proto.Coordinate
711711
return xerrors.Errorf("unable to convert bytes to UUID: %w", err)
712712
}
713713

714+
if !c.tunnels.tunnelExists(src.id, dstID) {
715+
return xerrors.Errorf("tunnel does not exist between %s and %s", src.id.String(), dstID.String())
716+
}
717+
714718
dst, ok := c.peers[dstID]
715719
if ok {
716720
select {

tailnet/coordinator_test.go

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,28 @@ func TestCoordinator(t *testing.T) {
422422
clientID := uuid.New()
423423
agentID := uuid.New()
424424

425-
aReq, _ := coordinator.Coordinate(ctx, agentID, agentID.String(), tailnet.AgentCoordinateeAuth{ID: agentID})
426-
_, cRes := coordinator.Coordinate(ctx, clientID, clientID.String(), tailnet.ClientCoordinateeAuth{AgentID: agentID})
425+
aReq, aRes := coordinator.Coordinate(ctx, agentID, agentID.String(), tailnet.AgentCoordinateeAuth{ID: agentID})
426+
cReq, cRes := coordinator.Coordinate(ctx, clientID, clientID.String(), tailnet.ClientCoordinateeAuth{AgentID: agentID})
427+
428+
{
429+
nk, err := key.NewNode().Public().MarshalBinary()
430+
require.NoError(t, err)
431+
dk, err := key.NewDisco().Public().MarshalText()
432+
require.NoError(t, err)
433+
cReq <- &proto.CoordinateRequest{UpdateSelf: &proto.CoordinateRequest_UpdateSelf{
434+
Node: &proto.Node{
435+
Id: 3,
436+
Key: nk,
437+
Disco: string(dk),
438+
},
439+
}}
440+
}
441+
442+
cReq <- &proto.CoordinateRequest{AddTunnel: &proto.CoordinateRequest_Tunnel{
443+
Id: agentID[:],
444+
}}
445+
446+
testutil.RequireRecvCtx(ctx, t, aRes)
427447

428448
aReq <- &proto.CoordinateRequest{ReadyForHandshake: []*proto.CoordinateRequest_ReadyForHandshake{{
429449
Id: clientID[:],
@@ -434,6 +454,44 @@ func TestCoordinator(t *testing.T) {
434454
require.Equal(t, proto.CoordinateResponse_PeerUpdate_READY_FOR_HANDSHAKE, ack.PeerUpdates[0].Kind)
435455
require.Equal(t, agentID[:], ack.PeerUpdates[0].Id)
436456
})
457+
458+
t.Run("AgentAck_NoPermission", func(t *testing.T) {
459+
t.Parallel()
460+
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
461+
coordinator := tailnet.NewCoordinator(logger)
462+
ctx := testutil.Context(t, testutil.WaitShort)
463+
464+
clientID := uuid.New()
465+
agentID := uuid.New()
466+
467+
aReq, _ := coordinator.Coordinate(ctx, agentID, agentID.String(), tailnet.AgentCoordinateeAuth{ID: agentID})
468+
_, _ = coordinator.Coordinate(ctx, clientID, clientID.String(), tailnet.ClientCoordinateeAuth{AgentID: agentID})
469+
470+
nk, err := key.NewNode().Public().MarshalBinary()
471+
require.NoError(t, err)
472+
dk, err := key.NewDisco().Public().MarshalText()
473+
require.NoError(t, err)
474+
aReq <- &proto.CoordinateRequest{UpdateSelf: &proto.CoordinateRequest_UpdateSelf{
475+
Node: &proto.Node{
476+
Id: 3,
477+
Key: nk,
478+
Disco: string(dk),
479+
},
480+
}}
481+
482+
require.Eventually(t, func() bool {
483+
return coordinator.Node(agentID) != nil
484+
}, testutil.WaitShort, testutil.IntervalFast)
485+
486+
aReq <- &proto.CoordinateRequest{ReadyForHandshake: []*proto.CoordinateRequest_ReadyForHandshake{{
487+
Id: clientID[:],
488+
}}}
489+
490+
// The agent node should disappear, indicating it was booted off.
491+
require.Eventually(t, func() bool {
492+
return coordinator.Node(agentID) == nil
493+
}, testutil.WaitShort, testutil.IntervalFast)
494+
})
437495
}
438496

439497
// TestCoordinator_AgentUpdateWhileClientConnects tests for regression on

tailnet/tunnel.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ func (s *tunnelStore) findTunnelPeers(id uuid.UUID) []uuid.UUID {
151151
return out
152152
}
153153

154+
func (s *tunnelStore) tunnelExists(src, dst uuid.UUID) bool {
155+
_, srcOK := s.bySrc[src][dst]
156+
_, dstOK := s.byDst[src][dst]
157+
return srcOK || dstOK
158+
}
159+
154160
func (s *tunnelStore) htmlDebug() []HTMLTunnel {
155161
out := make([]HTMLTunnel, 0)
156162
for src, dsts := range s.bySrc {

tailnet/tunnel_internal_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,18 @@ func TestTunnelStore_RemoveAll(t *testing.T) {
4343
require.Len(t, uut.findTunnelPeers(p2), 0)
4444
require.Len(t, uut.findTunnelPeers(p3), 0)
4545
}
46+
47+
func TestTunnelStore_TunnelExists(t *testing.T) {
48+
t.Parallel()
49+
p1 := uuid.UUID{1}
50+
p2 := uuid.UUID{2}
51+
uut := newTunnelStore()
52+
require.False(t, uut.tunnelExists(p1, p2))
53+
require.False(t, uut.tunnelExists(p2, p1))
54+
uut.add(p1, p2)
55+
require.True(t, uut.tunnelExists(p1, p2))
56+
require.True(t, uut.tunnelExists(p2, p1))
57+
uut.remove(p1, p2)
58+
require.False(t, uut.tunnelExists(p1, p2))
59+
require.False(t, uut.tunnelExists(p2, p1))
60+
}

0 commit comments

Comments
 (0)