(defparameter *allowed-commands* '("ls" "git" "rg" "grep" "date" "echo" "cat" "node" "python3" "sbcl")) (defparameter *shell-metacharacters* '(#\; #\& #\| #\> #\< #\$ #\` #\\ #\!)) (defun shell-command-safe-p (cmd-string) "Returns T if the command string contains no dangerous metacharacters." (not (some (lambda (char) (find char cmd-string)) *shell-metacharacters*))) (defun execute-shell-safely (action context) (let* ((payload (getf action :PAYLOAD)) (cmd-string (getf payload :cmd)) (executable (car (uiop:split-string (string-trim " " cmd-string) :separator '(#\Space))))) (cond ((not (shell-command-safe-p cmd-string)) (opencortex:inject-stimulus `(:TYPE :EVENT :PAYLOAD (:SENSOR :shell-response :cmd ,cmd-string :stdout "" :stderr "ERROR - Security Violation: Dangerous metacharacters detected." :exit-code 1)) :stream (getf context :reply-stream))) ((not (member executable *allowed-commands* :test #'string=)) (opencortex:inject-stimulus `(:TYPE :EVENT :PAYLOAD (:SENSOR :shell-response :cmd ,cmd-string :stdout "" :stderr "ERROR - Command not in security whitelist." :exit-code 1)) :stream (getf context :reply-stream))) (t (multiple-value-bind (stdout stderr exit-code) (uiop:run-program cmd-string :output :string :error-output :string :ignore-error-status t) (opencortex:inject-stimulus `(:TYPE :EVENT :PAYLOAD (:SENSOR :shell-response :cmd ,cmd-string :stdout ,(or stdout "") :stderr ,(or stderr "") :exit-code ,exit-code)) :stream (getf context :reply-stream))))))) (defun trigger-skill-shell-actuator (context) (let ((type (getf context :TYPE)) (payload (getf context :PAYLOAD))) (and (eq type :EVENT) (eq (getf payload :SENSOR) :shell-response)))) (defun probabilistic-skill-shell-actuator (context) (let* ((p (getf context :PAYLOAD)) (cmd (getf p :cmd)) (stdout (getf p :stdout)) (stderr (getf p :stderr)) (exit-code (getf p :exit-code))) (format nil "SHELL COMMAND RESULT: Command: ~a Exit Code: ~a STDOUT: ~a STDERR: ~a" cmd exit-code stdout stderr))) (opencortex:register-actuator :shell #'execute-shell-safely) (defskill :skill-shell-actuator :priority 80 :trigger #'trigger-skill-shell-actuator :probabilistic #'probabilistic-skill-shell-actuator :deterministic (lambda (action context) (declare (ignore context)) action))