feat: add ProxyStream handler with scoped single-use auth

This commit is contained in:
2026-07-29 12:50:20 +01:00
parent 8fcda63742
commit a000703199
2 changed files with 47 additions and 5 deletions
+47
View File
@@ -0,0 +1,47 @@
package grpcserver
import (
"log"
"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb"
"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/proxy"
"gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/services"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// ProxyStream carries one console TCP connection. The agent opens it after
// dialling its own loopback address, and authenticates with the same agent
// token as the command stream plus the single-use proxy_id it was handed.
func (s *vantageServer) ProxyStream(stream pb.Vantage_ProxyStreamServer) error {
msg, err := stream.Recv()
if err != nil {
return status.Errorf(codes.InvalidArgument, "expected initial open message: %v", err)
}
if msg.Open == nil {
return status.Error(codes.InvalidArgument, "first message must be open")
}
srv, err := services.ValidateAgentToken(msg.Open.ServerId, msg.Open.AgentToken)
if err != nil {
return status.Error(codes.Unauthenticated, "invalid agent token")
}
if err := serveProxy(proxy.Default, msg.Open, srv.InstanceID, stream); err != nil {
// The reason is deliberately not returned to the agent: an unknown and a
// foreign proxy_id must be indistinguishable.
log.Printf("proxy %s (server %s): %v", msg.Open.ProxyId, msg.Open.ServerId, err)
return status.Error(codes.PermissionDenied, "proxy session unavailable")
}
return nil
}
// serveProxy claims the pending session and relays it. Split out from the gRPC
// method so the authorisation matrix is testable without a real stream.
func serveProxy(reg *proxy.Registry, open *pb.ProxyOpen, instanceID string, stream proxy.AgentStream) error {
entry, err := reg.Claim(instanceID, open.ServerId, open.ProxyId)
if err != nil {
return err
}
return entry.Session.Serve(stream)
}
-5
View File
@@ -223,11 +223,6 @@ func (s *vantageServer) CommandStream(stream pb.Vantage_CommandStreamServer) err
}
}
// ProxyStream is stubbed here; Task 4 implements the real relay handler.
func (s *vantageServer) ProxyStream(stream pb.Vantage_ProxyStreamServer) error {
return status.Errorf(codes.Unimplemented, "method ProxyStream not implemented")
}
func StartGRPC(port int) error {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {