safe 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #! /usr/local/bin/guile -s
  2. !#
  3. ;;; examples/safe/safe -- Example for safe (sand-boxed) evaluation.
  4. ;;; Commentary:
  5. ;;; This is a demo program for evaluating arbitrary (untrusted) Scheme
  6. ;;; code in a controlled, safe environment. Evaluation in safe
  7. ;;; environments restricts the evaluated code's access to some given
  8. ;;; primitives, which are considered `safe', that means which cannot
  9. ;;; do any harm to the world outside of Guile (creating/deleting files
  10. ;;; etc.)
  11. ;;;
  12. ;;; *Note* that the files in this directory are only suitable for
  13. ;;; demonstration purposes, if you have to implement safe evaluation
  14. ;;; mechanisms in important environments, you will have to do more
  15. ;;; than shown here -- for example disabling input/output operations.
  16. ;;; Author: Martin Grabmueller
  17. ;;; Date: 2001-05-30
  18. ;;; Code:
  19. ;; Safe module creation is implemented in this module:
  20. ;;
  21. (use-modules (ice-9 safe))
  22. ;; This is the main program. It expects one parameter in the format
  23. ;; returned by (command-line) and expects that exactly one file name
  24. ;; is passed in this list (after the script name, which is passed as
  25. ;; the 0th parameter.)
  26. ;;
  27. ;; The given file is opened for reading, one expression after the
  28. ;; other is read and evaluated in a safe environment. All exceptions
  29. ;; caused by this evaluation are caught and printed out.
  30. ;;
  31. (define (main cmd-line)
  32. ;; Internal definition of the procedure which prints usage
  33. ;; information.
  34. ;;
  35. (define (display-help)
  36. (display "Usage: safe FILENAME")
  37. (newline)
  38. (quit 1))
  39. ;; Check that we received exactly one command line argument after
  40. ;; the script name
  41. ;;
  42. (if (not (= (length cmd-line) 2))
  43. (display-help)
  44. (let ((port (open-input-file (cadr cmd-line)))
  45. ;; Create the safe module.
  46. (safe-module (make-safe-module)))
  47. ;; Read one expression a time.
  48. (let lp ((expr (read port)))
  49. ;; End of file? -> Return.
  50. (if (eof-object? expr)
  51. #t
  52. (catch #t
  53. (lambda ()
  54. ;; Evaluate the expression in the safe environment.
  55. (eval expr safe-module)
  56. ;; ... and read the next expression if no error occured.
  57. (lp (read port)))
  58. ;; Handle exceptions. This procedure will be called when an
  59. ;; error occurs while evaluating the expression. It just
  60. ;; prints out a message telling so and returns from the
  61. ;; evaluation loop, thus terminating the program.
  62. ;;
  63. (lambda args
  64. (display "** Exception: ")
  65. (write args)
  66. (newline))))))))
  67. ;; Start the main program.
  68. ;;
  69. (main (command-line))
  70. ;; Local variables:
  71. ;; mode: scheme
  72. ;; End: