Retrack the agent connection once it is wrapped with the granted peer address

This commit is contained in:
Viktor Liu
2026-09-23 15:05:30 +02:00
parent c26b17653a
commit 9ede661bab
3 changed files with 26 additions and 13 deletions
-11
View File
@@ -293,14 +293,3 @@ func dialAgentWithRetry(ctx context.Context, addr string) (net.Conn, error) {
}
return nil, lastErr
}
// retrackConn replaces a tracked raw connection with the wrapper its handler
// will actually hold, so shutdown and the handler's own untrackConn agree on
// which object is registered. Service mode only: that is where an accepted
// connection is wrapped before the handler sees it.
func (s *Server) retrackConn(raw, wrapped net.Conn) {
s.sessionsMu.Lock()
delete(s.acceptedConns, raw)
s.acceptedConns[wrapped] = struct{}{}
s.sessionsMu.Unlock()
}
+16 -2
View File
@@ -618,6 +618,16 @@ func (s *Server) trackConn(c net.Conn) {
s.sessionsMu.Unlock()
}
// retrackConn replaces a tracked raw connection with the wrapper its handler
// will actually hold, so shutdown, connAuth registration and the handler's own
// untrackConn all agree on which object is registered.
func (s *Server) retrackConn(raw, wrapped net.Conn) {
s.sessionsMu.Lock()
delete(s.acceptedConns, raw)
s.acceptedConns[wrapped] = struct{}{}
s.sessionsMu.Unlock()
}
// untrackConn forgets a connection once its handler is returning.
func (s *Server) untrackConn(c net.Conn) {
s.sessionsMu.Lock()
@@ -1126,8 +1136,12 @@ func (s *Server) handleConnection(conn net.Conn) {
}
// Behind the daemon the accepted address is only the local socket; the
// remote peer is the one the daemon vouched for in the grant.
conn = withGrantPeer(conn, grant)
connLog = s.log.WithField("remote", conn.RemoteAddr().String())
if wrapped := withGrantPeer(conn, grant); wrapped != conn {
s.retrackConn(conn, wrapped)
defer s.untrackConn(wrapped)
conn = wrapped
connLog = s.log.WithField("remote", conn.RemoteAddr().String())
}
header, err := s.readConnectionHeader(conn)
if err != nil {
connLog.Infof("VNC connection rejected: header read failed: %v", err)
+10
View File
@@ -357,6 +357,16 @@ func TestAgentToken_MatchAllowsHandshake(t *testing.T) {
sessions := srv.ActiveSessions()
require.Len(t, sessions, 1, "one session must be active")
assert.Equal(t, peer, sessions[0].RemoteAddress, "the session must report the grant's peer")
// Shutdown and connAuth cleanup key on the tracked connection, so it must
// be the wrapper the handler registers everything under, not the raw one.
srv.sessionsMu.Lock()
var tracked []string
for c := range srv.acceptedConns {
tracked = append(tracked, c.RemoteAddr().String())
}
srv.sessionsMu.Unlock()
assert.Equal(t, []string{peer}, tracked, "the wrapped connection must be the tracked one")
}
func TestSessionMode_RejectedWhenNoVMGR(t *testing.T) {