add elevated flag to shell and callPromotedTool; thread through to executeElevated
This commit is contained in:
parent
9ea56242c3
commit
d5c591ad26
|
|
@ -139,9 +139,10 @@ func (lw *limitedWriter) Write(p []byte) (n int, err error) {
|
|||
// dispatchShell handles the shell tool: a single bash command.
|
||||
func dispatchShell(ctx context.Context, e *Server, args json.RawMessage) (string, error) {
|
||||
var a struct {
|
||||
Cmd string `json:"cmd"`
|
||||
Timeout int `json:"timeout"`
|
||||
Sandbox string `json:"sandbox"`
|
||||
Cmd string `json:"cmd"`
|
||||
Timeout int `json:"timeout"`
|
||||
Sandbox string `json:"sandbox"`
|
||||
Elevated bool `json:"elevated"`
|
||||
}
|
||||
if err := json.Unmarshal(args, &a); err != nil {
|
||||
return "", fmt.Errorf("shell: bad args: %w", err)
|
||||
|
|
@ -153,6 +154,12 @@ func dispatchShell(ctx context.Context, e *Server, args json.RawMessage) (string
|
|||
if timeout <= 0 {
|
||||
timeout = 30
|
||||
}
|
||||
if a.Elevated {
|
||||
e.wdMu.RLock()
|
||||
workDir := e.cwd
|
||||
e.wdMu.RUnlock()
|
||||
return e.executeElevated(ctx, a.Cmd, workDir, timeout)
|
||||
}
|
||||
sandboxName := a.Sandbox
|
||||
if sandboxName == "" {
|
||||
sandboxName = "default"
|
||||
|
|
|
|||
|
|
@ -149,9 +149,10 @@ timeout applies to each call (default: 30s). A non-zero exit is an error.`,
|
|||
"type": "object",
|
||||
"required": ["cmd"],
|
||||
"properties": {
|
||||
"cmd": {"type": "string", "description": "Bash command to execute."},
|
||||
"timeout": {"type": "integer", "description": "Timeout in seconds (default: 30). Use 0 for no timeout."},
|
||||
"sandbox": {"type": "string", "description": "Sandbox profile name (default: default)."}
|
||||
"cmd": {"type": "string", "description": "Bash command to execute."},
|
||||
"timeout": {"type": "integer", "description": "Timeout in seconds (default: 30). Use 0 for no timeout."},
|
||||
"sandbox": {"type": "string", "description": "Sandbox profile name (default: default)."},
|
||||
"elevated": {"type": "boolean", "description": "Run outside the sandbox via elevation broker."}
|
||||
}
|
||||
}`),
|
||||
},
|
||||
|
|
@ -273,7 +274,7 @@ func (e *Server) SetToolRegistry(r *Registry, sessionID string) {
|
|||
}
|
||||
|
||||
// callPromotedTool executes a tool promoted via the registry by running the
|
||||
// script file directly inside the sandbox.
|
||||
// script file inside the sandbox, or elevated if the args request it.
|
||||
func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.RawMessage) (json.RawMessage, error) {
|
||||
// Resolve script path.
|
||||
if strings.Contains(tool, "/") || strings.Contains(tool, "..") {
|
||||
|
|
@ -281,8 +282,9 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra
|
|||
}
|
||||
path := filepath.Join(ToolsPath(), tool)
|
||||
|
||||
// Parse positional args into a shell command string.
|
||||
// Parse args — extract positional args and optional elevated flag.
|
||||
var positional []string
|
||||
elevated := false
|
||||
var argMap map[string]interface{}
|
||||
if err := json.Unmarshal(args, &argMap); err == nil {
|
||||
if argsArr, ok := argMap["args"]; ok {
|
||||
|
|
@ -292,10 +294,14 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra
|
|||
}
|
||||
}
|
||||
}
|
||||
if e, ok := argMap["elevated"]; ok {
|
||||
if b, ok := e.(bool); ok {
|
||||
elevated = b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build a shell command that runs the tool script with its args.
|
||||
// Quote each arg for safe shell passing.
|
||||
quoted := make([]string, 0, len(positional)+1)
|
||||
quoted = append(quoted, path)
|
||||
for _, a := range positional {
|
||||
|
|
@ -303,8 +309,16 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra
|
|||
}
|
||||
code := strings.Join(quoted, " ")
|
||||
|
||||
// Execute through the sandbox via executeWithStdin.
|
||||
result, err := e.executeWithStdin(ctx, code, "bash", 30, "default", false, "")
|
||||
var result string
|
||||
var err error
|
||||
if elevated {
|
||||
e.wdMu.RLock()
|
||||
workDir := e.cwd
|
||||
e.wdMu.RUnlock()
|
||||
result, err = e.executeElevated(ctx, code, workDir, 30)
|
||||
} else {
|
||||
result, err = e.executeWithStdin(ctx, code, "bash", 30, "default", false, "")
|
||||
}
|
||||
if err != nil {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"isError": true,
|
||||
|
|
|
|||
Reference in New Issue