Product Site

13.1.1. Example

The following agent program includes all the actions for which the security manager defines checkpoints (for example, by calling an external function).
Example 13.1. Agent Program
/* Agent */
"echo Hello There"
call rxfuncadd "rxcalcsqrt", "rxmath", "rxcalcsqrt"
say result
say syssleep(1)
say linein("./profile")
say .methods
.json~define("")
::requires json.cls

The following server implements the security manager with three levels of security. For each action the security manager must check (for example, by calling an external routine):
  1. The audit manager (Dumper class) writes a record of the event but then permits the action.
  2. The closed cell manager (noWay class) does not permit the action to take place and raises an error.
  3. The replacement execution environment (Replacer class, a subclass of the noWay class) replaces the prohibited action with a different action.
Example 13.2. Example of Server Implementing Security Manager
/* 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