/* Server implements security manager */
parse arg program
routine = .Routine~newFile(program)
say "Calling program" program "with an audit manager:"
pull
routine~setSecurityManager(.Dumper~new(.stderr))
routine~call
say "Calling program" program "with a function replacement execution environment:"
pull
routine~setSecurityManager(.Replacer~new)
routine~call
say "Calling program" program "with a closed cell manager:"
pull
routine~setSecurityManager(.noWay~new)
signal on syntax
routine~call
exit
syntax:
say "Agent program terminated with an authorization failure"
say condition("additional")
exit
-- A Security Manager that keeps an audit record, and permits the request to run
::class Dumper public
::method init
-- save our target stream for output
expose stream
use arg stream
-- unknown will trap all Security Manager checkpoints
::method unknown
expose stream -- we write to our target stream
use arg name, args -- actual message name and arguments
-- write an audit record
stream~lineout(.DateTime~new "Called for event" name)
info = args[1] -- info directory is the first arg
do name over info -- write the info directory contents
stream~lineout(.DateTime~new "Info item" name":" info[name])
end
return 0 -- allow this to proceed
-- A closed cell Security Manager blocking all requests
::class noWay
-- unknown will trap all Security Manager checkpoints
::method unknown
-- raise an error for each checkpoint
raise syntax 98.948 array(arg(1) "blocked by Security manager")
-- A Security Manager that replaces prohibited actions with a different one
::class Replacer subclass noWay -- inherit restrictive UNKNOWN method
-- command checkpoint
::method command
use arg info
info~rc = 1234 -- replace the command return code
info~failure = .true -- raise a FAILURE condition
return 1 -- we handled this
-- external call checkpoint
::method call
use arg info
info~result = "blocked"
return 1 -- we handled this
-- STREAM checkpoint
::method stream
use arg info
-- always replace with a different stream
info~stream = .stream~new("SecurityManager.txt")
return 1 -- we handled this
-- .local variable lookup
::method local
return 1 -- handle. but return no value
-- .environment variable lookup
::method environment
return 1 -- handle. but return no value
-- protected method invocation
::method method
use arg info
info~result = "blocked"
return 1 -- we handled this
-- ::REQUIRES directive
::method requires
use arg info
info~name = "SecurityManager.cls"
info~securitymanager = self -- load under this authority
return 1 -- we handled this