MzScheme offers several mechanisms for managing security:
Custodians (section 9.2) manage resource allocation.
Security guards (section 9.1) control access to the filesystem and network.
Inspectors (section 4.5) control access to the content of otherwise opaque structures.
Namespaces (section 8) control access to Scheme bindings.
All security mechanisms rely on thread-specific parameters (see section 7.7).
A security guard provides a set of access-checking
procedures to be called when a thread initiates access of a file,
directory, or network connection through a primitive procedure. For
example, when a thread calls
, the thread's
current security guard is consulted to check whether the thread is
allowed read access to the file. If access is granted, the thread
receives a port that it may use indefinitely, regardless of changes
to the security guard (although the port's custodian could shut down
the port; see section 9.2).open-input-file
A thread's current security guard is determined by the
current-security-guard
parameter (see
section 7.7.1.8). Every security guard has a
parent, and a parent's access procedures are called whenever a
child's access procedures are called. Thus, a thread cannot increase
its own access arbitrarily by installing a new guard. The initial
security guard enforces no access restrictions other than those
enforced by the host platform.
(make-security-guard
parent-security-guard file-proc network-proc
)
creates a new security guard whose parent is
parent-security-guard
.
The file-proc
procedure must accept three arguments:
a symbol for the primitive procedure that triggered the access check, which is useful for raising an exception to deny access.
an immutable string representing a pathname, or #f
to
check access for pathless queries, such as
(
, current-directory
)(
, and
filesystem-root-list
)(
. A path string provided to
find-system-path
...)file-proc
is not processed at all before checking access; it
may be a relative path, and it may be ill-formed.
an immutable list containing one or more of the following symbols:
'read
-- read a file or directory
'write
-- modify or create a file or
directory
'delete
-- delete a file or directory
'exists
-- determine whether a file or
directory exists, or that a path string is well-formed
The 'exists
symbol is never combined with other symbols in
the last argument to file-proc
, but any other combination is
possible. When the second argument to file-proc
is #f
,
the last argument always contains only 'exists
.
The network-proc
procedure must accept four arguments:
a symbol for the primitive operation that triggered the access check, which is useful for raising an exception to deny access.
an immutable string representing the target hostname for a
client connection or the accepting hostname for a listening server;
#f
for a listening server or UDP socket that accepts
connections at all of the host's address; or #f
an unbound
UDP socket.
an exact integer between 1
and 65535
(inclusive) representing the port number, or #f
for an
unbound UDP socket. In the case of a client connection, the port
number is the target port on the server. For a listening server, the
port number is the local port number.
a symbol, either 'client
or 'server
,
indicating whether the check is for the creation of a client
connection or a listening server. The opening of an unbound UDP
socket is identified as a 'client
connection; explicitly
binding the socket is identified as a 'server
action.
The return value of file-proc
or network-proc
is
ignored. To deny access, the procedure must raise an exception or
otherwise escape from the context of the primitive call. If the
procedure returns, the parent's corresponding procedure is called on
the same inputs, and so on up the chain of security guards.
The file-proc
and network-proc
procedures are invoked in
the thread that called the access-checked primitive. Breaks may or
may not be enabled (see section 6.6). Full continuation
jumps are blocked going into or out of the file-proc
or
network-proc
call (see section 6.3).
(security-guard?
v
)
returns #t
if v
is a
security guard value, #f
otherwise.
A custodian manages a collection of threads, file-stream
ports, subprocess ports, TCP ports, TCP listeners, and UDP
sockets.14
Whenever a thread, file-stream port, process port, TCP port, TCP
listener, or UDP socket is created, it is placed under the management
of the current custodian (as determined by the
current-custodian
parameter; see
section 7.7.1.8).
The only operation on a custodian is to shut down all of its managed
values via
. In other words,
custodian-shutdown-all
generalizes custodian-shutdown-all
to
forcibly and immediately close a set of ports, TCP connections, etc.,
as well as terminate a set of threads. For example, web server might
use a custodian to manage all of the resources of a particular
session so that the session can be cleanly terminated if it
exceeds its allowed lifetime.kill-thread
The values managed by a custodian are only weakly held by the custodian. As a result, a will (see section 13.2) can be executed for a value that is managed by a custodian. In addition, a custodian only weakly references its subordinate custodians; if a subordinate custodian is unreferenced but has its own subordinates, then the custodian may be collected, at which point its subordinates become immediately subordinate to the collected custodian's superordiate custodian.
(make-custodian
[custodian
])
creates a new custodian that is
subordinate to the custodian custodian
. When custodian
is
directed (via
) to shut down all of its
managed values, the new subordinate custodian is automatically
directed to shut down its managed values as well. The default value
for custodian-shutdown-all
custodian
is the current custodian.
(custodian-shutdown-all
custodian
)
kills all
threads,15
closes all open ports, and closes all active TCP listeners and UDP
sockets that are managed by the
custodian custodian
. If custodian
manages the current
thread, the custodian shuts down all other objects before killing the
current thread.
(custodian?
v
)
returns #t
if v
is a custodian value,
#f
otherwise.
(custodian-managed-list
custodian super-custodian
)
returns a list
of immediately managed objects and subordinate custodians for
custodian
, where custodian
is itself subordinate to
super-custodian
(directly or indirectly). If custodian
is
not strictly subordinate to super-custodian
, the
exn:application:mismatch
exception is raised.
(custodian-require-memory
need-k thunk
)
registers a require check
if MzScheme is compiled with support for memory accounting, otherwise
the exn:misc:unsupported
exception is raised. If a check is registered, and if
MzScheme later reaches a state after garbage collection (see
section 13.3) where need-k
bytes are not
available to the current custodian, thunk
is invoked.
(custodian-limit-memory
custodian limit-k thunk
)
registers a
limit check if MzScheme is compiled with support for memory
accounting, otherwise the exn:misc:unsupported
exception is raised. If a check
is registered, and if MzScheme later reaches a state after garbage
collection (see section 13.3) where custodian
owns more than limit-k
bytes, then thunk
is invoked.