fix: avoid closing proxy relay listener before validating remote source
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user