(defnk new-sandbox
"Creates a sandbox that evaluates the code string that it gets passed.
The given namespace will be keeped unless :remember-state is given a
number greater then zero. If :remember-state >= 1 the namespace will
be torn down for every call of the sandbox, but functions like def,
alter, dosync will be 'rememberd' and rerun on the next sandbox call.
Only remember-state commands are keeped in history, if one command in
the history causes an exception it is removed."
[:namespace (gensym "net.licenser.sandbox.box")
:tester secure-tester
:timeout *default-sandbox-timeout*
:context (-> (empty-perms-list) domain context)
:object-tester default-obj-tester
:remember-state 0]
(let [history (atom [])]
(fn sandbox-executor [form]
(let [form (dot-replace form)]
(if (tester form namespace)
(thunk-timeout
(fn timeout-box []
(sandbox
(fn sandbox-jvm-runnable-code []
(if (not (zero? remember-state))
(doseq [d @history]
(try
(let [r (binding [*read-eval* false *ns* (create-ns namespace) dot (dot-maker object-tester)] (refer 'clojure.core) (eval '(def dot net.licenser.sandbox/dot)) (eval d))]
(if (coll? r) (doall r) r))
(catch Exception e
(swap! history #(remove (partial = d) %))))))
(let [r (binding [*read-eval* false *ns* (create-ns namespace) dot (dot-maker object-tester)] (refer 'clojure.core) (eval '(def dot net.licenser.sandbox/dot)) (eval form))]
(if (and (not (zero? remember-state)) (has-state? form))
(do
(if (>= (count @history) remember-state)
(swap! history #(conj (rest %) form))
(swap! history conj form))
(remove-ns namespace)))
(if (coll? r) (doall r) r))) context)) timeout)
(throw (SecurityException. (str "Code did not pass sandbox guidelines:" (pr-str (find-bad-forms tester namespace form))))))))))
Used in 0 other vars
Comments top
No comments for new-sandbox. Log in to add a comment.