541 lines
26 KiB
Plaintext
541 lines
26 KiB
Plaintext
'\"
|
|
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
|
|
'\"
|
|
'\" See the file "license.terms" for information on usage and redistribution
|
|
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
'\"
|
|
'\" SCCS: @(#) interp.n 1.37 97/10/31 12:51:11
|
|
'\"
|
|
.so man.macros
|
|
.TH interp n 7.6 Tcl "Tcl Built-In Commands"
|
|
.BS
|
|
'\" Note: do not modify the .SH NAME line immediately below!
|
|
.SH NAME
|
|
interp \- Create and manipulate Tcl interpreters
|
|
.SH SYNOPSIS
|
|
\fBinterp \fIoption \fR?\fIarg arg ...\fR?
|
|
.BE
|
|
|
|
.SH DESCRIPTION
|
|
.PP
|
|
This command makes it possible to create one or more new Tcl
|
|
interpreters that co-exist with the creating interpreter in the
|
|
same application. The creating interpreter is called the \fImaster\fR
|
|
and the new interpreter is called a \fIslave\fR.
|
|
A master can create any number of slaves, and each slave can
|
|
itself create additional slaves for which it is master, resulting
|
|
in a hierarchy of interpreters.
|
|
.PP
|
|
Each interpreter is independent from the others: it has its own name
|
|
space for commands, procedures, and global variables.
|
|
A master interpreter may create connections between its slaves and
|
|
itself using a mechanism called an \fIalias\fR. An \fIalias\fR is
|
|
a command in a slave interpreter which, when invoked, causes a
|
|
command to be invoked in its master interpreter or in another slave
|
|
interpreter. The only other connections between interpreters are
|
|
through environment variables (the \fBenv\fR variable), which are
|
|
normally shared among all interpreters in the application. Note that the
|
|
name space for files (such as the names returned by the \fBopen\fR command)
|
|
is no longer shared between interpreters. Explicit commands are provided to
|
|
share files and to transfer references to open files from one interpreter
|
|
to another.
|
|
.PP
|
|
The \fBinterp\fR command also provides support for \fIsafe\fR
|
|
interpreters. A safe interpreter is a slave whose functions have
|
|
been greatly restricted, so that it is safe to execute untrusted
|
|
scripts without fear of them damaging other interpreters or the
|
|
application's environment. For example, all IO channel creation
|
|
commands and subprocess creation commands are made inaccessible to safe
|
|
interpreters.
|
|
.VS
|
|
See SAFE INTERPRETERS below for more information on
|
|
what features are present in a safe interpreter.
|
|
The dangerous functionality is not removed from the safe interpreter;
|
|
instead, it is \fIhidden\fR, so that only trusted interpreters can obtain
|
|
access to it. For a detailed explanation of hidden commands, see
|
|
HIDDEN COMMANDS, below.
|
|
The alias mechanism can be used for protected communication (analogous to a
|
|
kernel call) between a slave interpreter and its master. See ALIAS
|
|
INVOCATION, below, for more details on how the alias mechanism works.
|
|
.VE
|
|
.PP
|
|
A qualified interpreter name is a proper Tcl lists containing a subset of its
|
|
ancestors in the interpreter hierarchy, terminated by the string naming the
|
|
interpreter in its immediate master. Interpreter names are relative to the
|
|
interpreter in which they are used. For example, if \fBa\fR is a slave of
|
|
the current interpreter and it has a slave \fBa1\fR, which in turn has a
|
|
slave \fBa11\fR, the qualified name of \fBa11\fR in \fBa\fR is the list
|
|
\fBa1 a11\fR.
|
|
.PP
|
|
The \fBinterp\fR command, described below, accepts qualified interpreter
|
|
names as arguments; the interpreter in which the command is being evaluated
|
|
can always be referred to as \fB{}\fR (the empty list or string). Note that
|
|
it is impossible to refer to a master (ancestor) interpreter by name in a
|
|
slave interpreter except through aliases. Also, there is no global name by
|
|
which one can refer to the first interpreter created in an application.
|
|
Both restrictions are motivated by safety concerns.
|
|
|
|
.VS
|
|
.SH "THE INTERP COMMAND"
|
|
.PP
|
|
.VE
|
|
The \fBinterp\fR command is used to create, delete, and manipulate
|
|
slave interpreters, and to share or transfer
|
|
channels between interpreters. It can have any of several forms, depending
|
|
on the \fIoption\fR argument:
|
|
.TP
|
|
\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcCmd\fR
|
|
Returns a Tcl list whose elements are the \fItargetCmd\fR and
|
|
\fIarg\fRs associated with the alias named \fIsrcCmd\fR
|
|
(all of these are the values specified when the alias was
|
|
created; it is possible that the actual source command in the
|
|
slave is different from \fIsrcCmd\fR if it was renamed).
|
|
.TP
|
|
\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcCmd\fR \fB{}\fR
|
|
Deletes the alias for \fIsrcCmd\fR in the slave interpreter identified by
|
|
\fIsrcPath\fR.
|
|
\fIsrcCmd\fR refers to the name under which the alias
|
|
was created; if the source command has been renamed, the renamed
|
|
command will be deleted.
|
|
.TP
|
|
\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcCmd\fR \fItargetPath\fR \fItargetCmd \fR?\fIarg arg ...\fR?
|
|
This command creates an alias between one slave and another (see the
|
|
\fBalias\fR slave command below for creating aliases between a slave
|
|
and its master). In this command, either of the slave interpreters
|
|
may be anywhere in the hierarchy of interpreters under the interpreter
|
|
invoking the command.
|
|
\fISrcPath\fR and \fIsrcCmd\fR identify the source of the alias.
|
|
\fISrcPath\fR is a Tcl list whose elements select a particular
|
|
interpreter. For example, ``\fBa b\fR'' identifies an interpreter
|
|
\fBb\fR, which is a slave of interpreter \fBa\fR, which is a slave
|
|
of the invoking interpreter. An empty list specifies the interpreter
|
|
invoking the command. \fIsrcCmd\fR gives the name of a new
|
|
command, which will be created in the source interpreter.
|
|
\fITargetPath\fR and \fItargetCmd\fR specify a target interpreter
|
|
and command, and the \fIarg\fR arguments, if any, specify additional
|
|
arguments to \fItargetCmd\fR which are prepended to any arguments specified
|
|
in the invocation of \fIsrcCmd\fR.
|
|
\fITargetCmd\fR may be undefined at the time of this call, or it may
|
|
already exist; it is not created by this command.
|
|
The alias arranges for the given target command to be invoked
|
|
in the target interpreter whenever the given source command is
|
|
invoked in the source interpreter. See ALIAS INVOCATION below for
|
|
more details.
|
|
.TP
|
|
\fBinterp\fR \fBaliases \fR?\fIpath\fR?
|
|
This command returns a Tcl list of the names of all the source commands for
|
|
aliases defined in the interpreter identified by \fIpath\fR.
|
|
.TP
|
|
\fBinterp\fR \fBcreate \fR?\fB\-safe\fR? ?\fB\-\|\-\fR? ?\fIpath\fR?
|
|
Creates a slave interpreter identified by \fIpath\fR and a new command,
|
|
called a \fIslave command\fR. The name of the slave command is the last
|
|
component of \fIpath\fR. The new slave interpreter and the slave command
|
|
are created in the interpreter identified by the path obtained by removing
|
|
the last component from \fIpath\fR. For example, if \fIpath is \fBa b
|
|
c\fR then a new slave interpreter and slave command named \fBc\fR are
|
|
created in the interpreter identified by the path \fBa b\fR.
|
|
The slave command may be used to manipulate the new interpreter as
|
|
described below. If \fIpath\fR is omitted, Tcl creates a unique name of the
|
|
form \fBinterp\fIx\fR, where \fIx\fR is an integer, and uses it for the
|
|
interpreter and the slave command. If the \fB\-safe\fR switch is specified
|
|
(or if the master interpreter is a safe interpreter), the new slave
|
|
interpreter will be created as a safe interpreter with limited
|
|
functionality; otherwise the slave will include the full set of Tcl
|
|
built-in commands and variables. The \fB\-\|\-\fR switch can be used to
|
|
mark the end of switches; it may be needed if \fIpath\fR is an unusual
|
|
value such as \fB\-safe\fR. The result of the command is the name of the
|
|
new interpreter. The name of a slave interpreter must be unique among all
|
|
the slaves for its master; an error occurs if a slave interpreter by the
|
|
given name already exists in this master.
|
|
.TP
|
|
\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR
|
|
Deletes zero or more interpreters given by the optional \fIpath\fR
|
|
arguments, and for each interpreter, it also deletes its slaves. The
|
|
command also deletes the slave command for each interpreter deleted.
|
|
For each \fIpath\fR argument, if no interpreter by that name
|
|
exists, the command raises an error.
|
|
.TP
|
|
\fBinterp\fR \fBeval\fR \fIpath arg \fR?\fIarg ...\fR?
|
|
This command concatenates all of the \fIarg\fR arguments in the same
|
|
fashion as the \fBconcat\fR command, then evaluates the resulting string as
|
|
a Tcl script in the slave interpreter identified by \fIpath\fR. The result
|
|
of this evaluation (including error information such as the \fBerrorInfo\fR
|
|
and \fBerrorCode\fR variables, if an error occurs) is returned to the
|
|
invoking interpreter.
|
|
.TP
|
|
\fBinterp exists \fIpath\fR
|
|
Returns \fB1\fR if a slave interpreter by the specified \fIpath\fR
|
|
exists in this master, \fB0\fR otherwise. If \fIpath\fR is omitted, the
|
|
invoking interpreter is used.
|
|
.VS "" BR
|
|
.TP
|
|
\fBinterp expose \fIpath\fR \fIhiddenName\fR ?\fIexposedCmdName\fR?
|
|
Makes the hidden command \fIhiddenName\fR exposed, eventually bringing
|
|
it back under a new \fIexposedCmdName\fR name (this name is currently
|
|
accepted only if it is a valid global name space name without any ::),
|
|
in the interpreter
|
|
denoted by \fIpath\fR.
|
|
If an exposed command with the targetted name already exists, this command
|
|
fails.
|
|
Hidden commands are explained in more detail in HIDDEN COMMANDS, below.
|
|
.TP
|
|
\fBinterp\fR \fBhide\fR \fIpath\fR \fIexposedCmdName\fR ?\fIhiddenCmdName\fR?
|
|
Makes the exposed command \fIexposedCmdName\fR hidden, renaming
|
|
it to the hidden command \fIhiddenCmdName\fR, or keeping the same name if
|
|
\fIhiddenCmdName\fR is not given, in the interpreter denoted
|
|
by \fIpath\fR.
|
|
If a hidden command with the targetted name already exists, this command
|
|
fails.
|
|
Currently both \fIexposedCmdName\fR and \fIhiddenCmdName\fR can
|
|
not contain namespace qualifiers, or an error is raised.
|
|
Commands to be hidden by \fBinterp hide\fR are looked up in the global
|
|
namespace even if the current namespace is not the global one. This
|
|
prevents slaves from fooling a master interpreter into hiding the wrong
|
|
command, by making the current namespace be different from the global one.
|
|
Hidden commands are explained in more detail in HIDDEN COMMANDS, below.
|
|
.TP
|
|
\fBinterp\fR \fBhidden\fR \fIpath\fR
|
|
Returns a list of the names of all hidden commands in the interpreter
|
|
identified by \fIpath\fR.
|
|
.TP
|
|
\fBinterp\fR \fBinvokehidden\fR \fIpath\fR ?\fB-global\fR \fIhiddenCmdName\fR ?\fIarg ...\fR?
|
|
Invokes the hidden command \fIhiddenCmdName\fR with the arguments supplied
|
|
in the interpreter denoted by \fIpath\fR. No substitutions or evaluation
|
|
are applied to the arguments.
|
|
If the \fB-global\fR flag is present, the hidden command is invoked at the
|
|
global level in the target interpreter; otherwise it is invoked at the
|
|
current call frame and can access local variables in that and outer call
|
|
frames.
|
|
Hidden commands are explained in more detail in HIDDEN COMMANDS, below.
|
|
.VE
|
|
.TP
|
|
\fBinterp issafe\fR ?\fIpath\fR?
|
|
Returns \fB1\fR if the interpreter identified by the specified \fIpath\fR
|
|
is safe, \fB0\fR otherwise.
|
|
.VS "" BR
|
|
.TP
|
|
\fBinterp marktrusted\fR \fIpath\fR
|
|
Marks the interpreter identified by \fIpath\fR as trusted. Does
|
|
not expose the hidden commands. This command can only be invoked from a
|
|
trusted interpreter.
|
|
The command has no effect if the interpreter identified by \fIpath\fR is
|
|
already trusted.
|
|
.VE
|
|
.TP
|
|
\fBinterp\fR \fBshare\fR \fIsrcPath channelId destPath\fR
|
|
Causes the IO channel identified by \fIchannelId\fR to become shared
|
|
between the interpreter identified by \fIsrcPath\fR and the interpreter
|
|
identified by \fIdestPath\fR. Both interpreters have the same permissions
|
|
on the IO channel.
|
|
Both interpreters must close it to close the underlying IO channel; IO
|
|
channels accessible in an interpreter are automatically closed when an
|
|
interpreter is destroyed.
|
|
.TP
|
|
\fBinterp\fR \fBslaves\fR ?\fIpath\fR?
|
|
Returns a Tcl list of the names of all the slave interpreters associated
|
|
with the interpreter identified by \fIpath\fR. If \fIpath\fR is omitted,
|
|
the invoking interpreter is used.
|
|
.TP
|
|
\fBinterp\fR \fBtarget\fR \fIpath alias\fR
|
|
Returns a Tcl list describing the target interpreter for an alias. The
|
|
alias is specified with an interpreter path and source command name, just
|
|
as in \fBinterp alias\fR above. The name of the target interpreter is
|
|
returned as an interpreter path, relative to the invoking interpreter.
|
|
If the target interpreter for the alias is the invoking interpreter then an
|
|
empty list is returned. If the target interpreter for the alias is not the
|
|
invoking interpreter or one of its descendants then an error is generated.
|
|
The target command does not have to be defined at the time of this invocation.
|
|
.TP
|
|
\fBinterp\fR \fBtransfer\fR \fIsrcPath channelId destPath\fR
|
|
Causes the IO channel identified by \fIchannelId\fR to become available in
|
|
the interpreter identified by \fIdestPath\fR and unavailable in the
|
|
interpreter identified by \fIsrcPath\fR.
|
|
|
|
.SH "SLAVE COMMAND"
|
|
.PP
|
|
For each slave interpreter created with the \fBinterp\fR command, a
|
|
new Tcl command is created in the master interpreter with the same
|
|
name as the new interpreter. This command may be used to invoke
|
|
various operations on the interpreter. It has the following
|
|
general form:
|
|
.CS
|
|
\fIslave command \fR?\fIarg arg ...\fR?
|
|
.CE
|
|
\fISlave\fR is the name of the interpreter, and \fIcommand\fR
|
|
and the \fIarg\fRs determine the exact behavior of the command.
|
|
The valid forms of this command are:
|
|
.TP
|
|
\fIslave \fBaliases\fR
|
|
Returns a Tcl list whose elements are the names of all the
|
|
aliases in \fIslave\fR. The names returned are the \fIsrcCmd\fR
|
|
values used when the aliases were created (which may not be the same
|
|
as the current names of the commands, if they have been
|
|
renamed).
|
|
.TP
|
|
\fIslave \fBalias \fIsrcCmd\fR
|
|
Returns a Tcl list whose elements are the \fItargetCmd\fR and
|
|
\fIarg\fRs associated with the alias named \fIsrcCmd\fR
|
|
(all of these are the values specified when the alias was
|
|
created; it is possible that the actual source command in the
|
|
slave is different from \fIsrcCmd\fR if it was renamed).
|
|
.TP
|
|
\fIslave \fBalias \fIsrcCmd \fB{}\fR
|
|
Deletes the alias for \fIsrcCmd\fR in the slave interpreter.
|
|
\fIsrcCmd\fR refers to the name under which the alias
|
|
was created; if the source command has been renamed, the renamed
|
|
command will be deleted.
|
|
.TP
|
|
\fIslave \fBalias \fIsrcCmd targetCmd \fR?\fIarg ..\fR?
|
|
Creates an alias such that whenever \fIsrcCmd\fR is invoked
|
|
in \fIslave\fR, \fItargetCmd\fR is invoked in the master.
|
|
The \fIarg\fR arguments will be passed to \fItargetCmd\fR as additional
|
|
arguments, prepended before any arguments passed in the invocation of
|
|
\fIsrcCmd\fR.
|
|
See ALIAS INVOCATION below for details.
|
|
.TP
|
|
\fIslave \fBeval \fIarg \fR?\fIarg ..\fR?
|
|
This command concatenates all of the \fIarg\fR arguments in
|
|
the same fashion as the \fBconcat\fR command, then evaluates
|
|
the resulting string as a Tcl script in \fIslave\fR.
|
|
The result of this evaluation (including error information
|
|
such as the \fBerrorInfo\fR and \fBerrorCode\fR variables, if an
|
|
error occurs) is returned to the invoking interpreter.
|
|
.VS "" BR
|
|
.TP
|
|
\fIslave \fBexpose \fIhiddenName \fR?\fIexposedCmdName\fR?
|
|
This command exposes the hidden command \fIhiddenName\fR, eventually bringing
|
|
it back under a new \fIexposedCmdName\fR name (this name is currently
|
|
accepted only if it is a valid global name space name without any ::),
|
|
in \fIslave\fR.
|
|
If an exposed command with the targetted name already exists, this command
|
|
fails.
|
|
For more details on hidden commands, see HIDDEN COMMANDS, below.
|
|
.TP
|
|
\fIslave \fBhide \fIexposedCmdName\fR ?\fIhiddenCmdName\fR?
|
|
This command hides the exposed command \fIexposedCmdName\fR, renaming it to
|
|
the hidden command \fIhiddenCmdName\fR, or keeping the same name if the
|
|
the argument is not given, in the \fIslave\fR interpreter.
|
|
If a hidden command with the targetted name already exists, this command
|
|
fails.
|
|
Currently both \fIexposedCmdName\fR and \fIhiddenCmdName\fR can
|
|
not contain namespace qualifiers, or an error is raised.
|
|
Commands to be hidden are looked up in the global
|
|
namespace even if the current namespace is not the global one. This
|
|
prevents slaves from fooling a master interpreter into hiding the wrong
|
|
command, by making the current namespace be different from the global one.
|
|
For more details on hidden commands, see HIDDEN COMMANDS, below.
|
|
.TP
|
|
\fIslave \fBhidden\fR
|
|
Returns a list of the names of all hidden commands in \fIslave\fR.
|
|
.TP
|
|
\fIslave \fBinvokehidden\fR ?\fB-global\fR \fIhiddenName \fR?\fIarg ..\fR?
|
|
This command invokes the hidden command \fIhiddenName\fR with the
|
|
supplied arguments, in \fIslave\fR. No substitutions or evaluations are
|
|
applied to the arguments.
|
|
If the \fB-global\fR flag is given, the command is invoked at the global
|
|
level in the slave; otherwise it is invoked at the current call frame and
|
|
can access local variables in that or outer call frames.
|
|
For more details on hidden commands, see HIDDEN
|
|
COMMANDS, below.
|
|
.VE
|
|
.TP
|
|
\fIslave \fBissafe\fR
|
|
Returns \fB1\fR if the slave interpreter is safe, \fB0\fR otherwise.
|
|
.VS "" BR
|
|
.TP
|
|
\fIslave \fBmarktrusted\fR
|
|
Marks the slave interpreter as trusted. Can only be invoked by a
|
|
trusted interpreter. This command does not expose any hidden
|
|
commands in the slave interpreter. The command has no effect if the slave
|
|
is already trusted.
|
|
.VE
|
|
|
|
.SH "SAFE INTERPRETERS"
|
|
.PP
|
|
A safe interpreter is one with restricted functionality, so that
|
|
is safe to execute an arbitrary script from your worst enemy without
|
|
fear of that script damaging the enclosing application or the rest
|
|
of your computing environment. In order to make an interpreter
|
|
safe, certain commands and variables are removed from the interpreter.
|
|
For example, commands to create files on disk are removed, and the
|
|
\fBexec\fR command is removed, since it could be used to cause damage
|
|
through subprocesses.
|
|
Limited access to these facilities can be provided, by creating
|
|
aliases to the master interpreter which check their arguments carefully
|
|
and provide restricted access to a safe subset of facilities.
|
|
For example, file creation might be allowed in a particular subdirectory
|
|
and subprocess invocation might be allowed for a carefully selected and
|
|
fixed set of programs.
|
|
.PP
|
|
A safe interpreter is created by specifying the \fB\-safe\fR switch
|
|
to the \fBinterp create\fR command. Furthermore, any slave created
|
|
by a safe interpreter will also be safe.
|
|
.PP
|
|
A safe interpreter is created with exactly the following set of
|
|
built-in commands:
|
|
.DS
|
|
.ta 1.2i 2.4i 3.6i
|
|
\fBafter append array break
|
|
case catch clock close
|
|
concat continue eof error
|
|
eval expr fblocked fileevent
|
|
flush for foreach format
|
|
gets global history if
|
|
incr info interp join
|
|
lappend lindex linsert list
|
|
llength lower lrange lreplace
|
|
lsearch lsort package pid
|
|
proc puts read rename
|
|
return scan seek set
|
|
split string subst switch
|
|
tell trace unset update
|
|
uplevel upvar vwait while\fR
|
|
.DE
|
|
.VS "" BR
|
|
The following commands are hidden by \fBinterp create\fR when it
|
|
creates a safe interpreter:
|
|
.DS
|
|
.ta 1.2i 2.4i 3.6i
|
|
\fBcd exec exit fconfigure
|
|
file glob load open
|
|
pwd socket source vwait\fR
|
|
.DE
|
|
These commands can be recreated later as Tcl procedures or aliases, or
|
|
re-exposed by \fBinterp expose\fR.
|
|
.VE
|
|
.PP
|
|
In addition, the \fBenv\fR variable is not present in a safe interpreter,
|
|
so it cannot share environment variables with other interpreters. The
|
|
\fBenv\fR variable poses a security risk, because users can store
|
|
sensitive information in an environment variable. For example, the PGP
|
|
manual recommends storing the PGP private key protection password in
|
|
the environment variable \fIPGPPASS\fR. Making this variable available
|
|
to untrusted code executing in a safe interpreter would incur a
|
|
security risk.
|
|
.PP
|
|
If extensions are loaded into a safe interpreter, they may also restrict
|
|
their own functionality to eliminate unsafe commands. For a discussion of
|
|
management of extensions for safety see the manual entries for
|
|
\fBSafe\-Tcl\fR and the \fBload\fR Tcl command.
|
|
|
|
.SH "ALIAS INVOCATION"
|
|
.PP
|
|
The alias mechanism has been carefully designed so that it can
|
|
be used safely when an untrusted script is executing
|
|
in a safe slave and the target of the alias is a trusted
|
|
master. The most important thing in guaranteeing safety is to
|
|
ensure that information passed from the slave to the master is
|
|
never evaluated or substituted in the master; if this were to
|
|
occur, it would enable an evil script in the slave to invoke
|
|
arbitrary functions in the master, which would compromise security.
|
|
.PP
|
|
When the source for an alias is invoked in the slave interpreter, the
|
|
usual Tcl substitutions are performed when parsing that command.
|
|
These substitutions are carried out in the source interpreter just
|
|
as they would be for any other command invoked in that interpreter.
|
|
The command procedure for the source command takes its arguments
|
|
and merges them with the \fItargetCmd\fR and \fIarg\fRs for the
|
|
alias to create a new array of arguments. If the words
|
|
of \fIsrcCmd\fR were ``\fIsrcCmd arg1 arg2 ... argN\fR'',
|
|
the new set of words will be
|
|
``\fItargetCmd arg arg ... arg arg1 arg2 ... argN\fR'',
|
|
where \fItargetCmd\fR and \fIarg\fRs are the values supplied when the
|
|
alias was created. \fITargetCmd\fR is then used to locate a command
|
|
procedure in the target interpreter, and that command procedure
|
|
is invoked with the new set of arguments. An error occurs if
|
|
there is no command named \fItargetCmd\fR in the target interpreter.
|
|
No additional substitutions are performed on the words: the
|
|
target command procedure is invoked directly, without
|
|
going through the normal Tcl evaluation mechanism.
|
|
Substitutions are thus performed on each word exactly once:
|
|
\fItargetCmd\fR and \fIargs\fR were substituted when parsing the command
|
|
that created the alias, and \fIarg1 - argN\fR are substituted when
|
|
the alias's source command is parsed in the source interpreter.
|
|
.PP
|
|
When writing the \fItargetCmd\fRs for aliases in safe interpreters,
|
|
it is very important that the arguments to that command never be
|
|
evaluated or substituted, since this would provide an escape
|
|
mechanism whereby the slave interpreter could execute arbitrary
|
|
code in the master. This in turn would compromise the security
|
|
of the system.
|
|
|
|
.VS
|
|
.SH "HIDDEN COMMANDS"
|
|
.PP
|
|
Safe interpreters greatly restrict the functionality available to Tcl
|
|
programs executing within them.
|
|
Allowing the untrusted Tcl program to have direct access to this
|
|
functionality is unsafe, because it can be used for a variety of
|
|
attacks on the environment.
|
|
However, there are times when there is a legitimate need to use the
|
|
dangerous functionality in the context of the safe interpreter. For
|
|
example, sometimes a program must be \fBsource\fRd into the interpreter.
|
|
Another example is Tk, where windows are bound to the hierarchy of windows
|
|
for a specific interpreter; some potentially dangerous functions, e.g.
|
|
window management, must be performed on these windows within the
|
|
interpreter context.
|
|
.PP
|
|
The \fBinterp\fR command provides a solution to this problem in the form of
|
|
\fIhidden commands\fR. Instead of removing the dangerous commands entirely
|
|
from a safe interpreter, these commands are hidden so they become
|
|
unavailable to Tcl scripts executing in the interpreter. However, such
|
|
hidden commands can be invoked by any trusted ancestor of the safe
|
|
interpreter, in the context of the safe interpreter, using \fBinterp
|
|
invoke\fR. Hidden commands and exposed commands reside in separate name
|
|
spaces. It is possible to define a hidden command and an exposed command by
|
|
the same name within one interpreter.
|
|
.PP
|
|
Hidden commands in a slave interpreter can be invoked in the body of
|
|
procedures called in the master during alias invocation. For example, an
|
|
alias for \fBsource\fR could be created in a slave interpreter. When it is
|
|
invoked in the slave interpreter, a procedure is called in the master
|
|
interpreter to check that the operation is allowable (e.g. it asks to
|
|
source a file that the slave interpreter is allowed to access). The
|
|
procedure then it invokes the hidden \fBsource\fR command in the slave
|
|
interpreter to actually source in the contents of the file. Note that two
|
|
commands named \fBsource\fR exist in the slave interpreter: the alias, and
|
|
the hidden command.
|
|
.PP
|
|
Because a master interpreter may invoke a hidden command as part of
|
|
handling an alias invocation, great care must be taken to avoid evaluating
|
|
any arguments passed in through the alias invocation.
|
|
Otherwise, malicious slave interpreters could cause a trusted master
|
|
interpreter to execute dangerous commands on their behalf. See the section
|
|
on ALIAS INVOCATION for a more complete discussion of this topic.
|
|
To help avoid this problem, no substitutions or evaluations are
|
|
applied to arguments of \fBinterp invokehidden\fR.
|
|
.PP
|
|
Safe interpreters are not allowed to invoke hidden commands in themselves
|
|
or in their descendants. This prevents safe slaves from gaining access to
|
|
hidden functionality in themselves or their descendants.
|
|
.PP
|
|
The set of hidden commands in an interpreter can be manipulated by a trusted
|
|
interpreter using \fBinterp expose\fR and \fBinterp hide\fR. The \fBinterp
|
|
expose\fR command moves a hidden command to the
|
|
set of exposed commands in the interpreter identified by \fIpath\fR,
|
|
potentially renaming the command in the process. If an exposed command by
|
|
the targetted name already exists, the operation fails. Similarly,
|
|
\fBinterp hide\fR moves an exposed command to the set of hidden commands in
|
|
that interpreter. Safe interpreters are not allowed to move commands
|
|
between the set of hidden and exposed commands, in either themselves or
|
|
their descendants.
|
|
.PP
|
|
Currently, the names of hidden commands cannot contain namespace
|
|
qualifiers, and you must first rename a command in a namespace to the
|
|
global namespace before you can hide it.
|
|
Commands to be hidden by \fBinterp hide\fR are looked up in the global
|
|
namespace even if the current namespace is not the global one. This
|
|
prevents slaves from fooling a master interpreter into hiding the wrong
|
|
command, by making the current namespace be different from the global one.
|
|
.VE
|
|
.SH CREDITS
|
|
.PP
|
|
This mechanism is based on the Safe-Tcl prototype implemented
|
|
by Nathaniel Borenstein and Marshall Rose.
|
|
|
|
.SH "SEE ALSO"
|
|
load(n), safe(n), Tcl_CreateSlave(3)
|
|
|
|
.SH KEYWORDS
|
|
alias, master interpreter, safe interpreter, slave interpreter
|