From 8fcda63742fa98a83e60c4cf37168e8c79b7faee Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Wed, 29 Jul 2026 12:47:35 +0100 Subject: [PATCH] fix: avoid closing proxy relay listener before validating remote source --- server/internal/proxy/session.go | 41 +++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/server/internal/proxy/session.go b/server/internal/proxy/session.go index 8d8cd0e..9217f21 100644 --- a/server/internal/proxy/session.go +++ b/server/internal/proxy/session.go @@ -6,6 +6,7 @@ import ( "io" "log" "net" + "os" "sync" "time" @@ -86,22 +87,34 @@ func (s *Session) Serve(stream AgentStream) error { _ = l.SetDeadline(time.Now().Add(s.timeout)) } - conn, err := s.listener.Accept() - if err != nil { - s.setReason("guacd_timeout") - return fmt.Errorf("waiting for guacd: %w", err) - } - // One connection only: nothing else may claim this port. - s.Close("") + // Accept until a connection from an allowed source arrives or the + // rendezvous deadline (set once, above) expires. A rejected connection is + // closed and the loop retries within the same deadline; the listener is + // only closed once we have a valid connection, the deadline expires, or + // Accept fails for a genuine (non-timeout) reason. + for { + conn, err := s.listener.Accept() + if err != nil { + var netErr net.Error + if errors.Is(err, os.ErrDeadlineExceeded) || (errors.As(err, &netErr) && netErr.Timeout()) { + s.setReason("guacd_timeout") + } else { + s.setReason("accept_failed") + } + return fmt.Errorf("waiting for guacd: %w", err) + } - if !allowedRemote(conn.RemoteAddr().String(), s.allowed) { - _ = conn.Close() - s.setReason("foreign_source") - return fmt.Errorf("relay connection from disallowed source %s", conn.RemoteAddr()) - } - defer conn.Close() + if !allowedRemote(conn.RemoteAddr().String(), s.allowed) { + _ = conn.Close() + continue + } - return s.relay(conn, stream) + // One connection only: nothing else may claim this port. + s.Close("") + defer conn.Close() + + return s.relay(conn, stream) + } } func (s *Session) relay(conn net.Conn, stream AgentStream) error {