104 lines
2.3 KiB
Go
104 lines
2.3 KiB
Go
// state.go - Server state management for toolsrv.
|
|
package fs
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"runtime"
|
|
"sync"
|
|
|
|
"ollie/cmd/toolsrv/internal/registry"
|
|
"ollie/virtfs"
|
|
)
|
|
|
|
// Server holds the state for the toolsrv 9P server.
|
|
type Server struct {
|
|
mu sync.RWMutex
|
|
|
|
secret string // set on first auth, verified on subsequent
|
|
token string // session token returned after auth
|
|
registry *registry.Registry // tool registry
|
|
yolo bool // skip sandbox
|
|
|
|
// Process management
|
|
Fs *State
|
|
}
|
|
|
|
// NewServer creates a new toolsrv server.
|
|
func NewServer() *Server {
|
|
return &Server{
|
|
Fs: NewState(""), // cwd set per-agent
|
|
}
|
|
}
|
|
|
|
// SetRegistry configures the tool registry.
|
|
func (s *Server) SetRegistry(r *registry.Registry) {
|
|
s.mu.Lock()
|
|
s.registry = r
|
|
s.Fs.SetRegistry(r)
|
|
s.mu.Unlock()
|
|
}
|
|
|
|
// SetYolo enables/disables sandbox bypass.
|
|
func (s *Server) SetYolo(yolo bool) {
|
|
s.mu.Lock()
|
|
s.yolo = yolo
|
|
s.Fs.SetYolo(yolo)
|
|
s.mu.Unlock()
|
|
}
|
|
|
|
// Authenticate handles secret verification.
|
|
// First call sets the secret; subsequent calls must match it.
|
|
// Returns (token, nil) on success, ("", error) on failure.
|
|
func (s *Server) Authenticate(clientSecret string) (string, error) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
if s.secret == "" {
|
|
// First auth - set the secret
|
|
s.secret = clientSecret
|
|
s.token = randomToken()
|
|
return s.token, nil
|
|
}
|
|
|
|
// Subsequent auth - verify secret
|
|
if clientSecret != s.secret {
|
|
return "", fmt.Errorf("authentication failed")
|
|
}
|
|
|
|
return s.token, nil
|
|
}
|
|
|
|
// Token returns the current session token (empty if not authenticated).
|
|
func (s *Server) Token() string {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
return s.token
|
|
}
|
|
|
|
// HostInfo returns platform info as key=value lines.
|
|
func (s *Server) HostInfo() string {
|
|
return fmt.Sprintf("platform=%s\narch=%s\n", runtime.GOOS, runtime.GOARCH)
|
|
}
|
|
|
|
// BuildTree creates the virtfs tree for this server.
|
|
func (s *Server) BuildTree() *virtfs.Tree {
|
|
return virtfs.BuildTree(Spec(s))
|
|
}
|
|
|
|
// GenerateSecret generates a random shared secret for toolsrv auth.
|
|
func GenerateSecret() (string, error) {
|
|
secret := make([]byte, 32)
|
|
if _, err := rand.Read(secret); err != nil {
|
|
return "", err
|
|
}
|
|
return hex.EncodeToString(secret), nil
|
|
}
|
|
|
|
func randomToken() string {
|
|
b := make([]byte, 16)
|
|
rand.Read(b)
|
|
return hex.EncodeToString(b)
|
|
}
|