The Woof! interpreter model
The Tcl language allows multiple interpreters within a single program and moreover provides for the ability to run code inside a safe interpreter that, for security reasons, can be restricted in terms of the commands it can execute. For example, commands that execute programs or write to disk can be either disabled or enabled with restrictions. The purpose of running code in a safe interpreter is to make it harder for an attacker to penetrate or damage the system even in the presence of programming bugs and security holes. See Security for more details.
Woof! makes use of this very useful Tcl capability by splitting the runtime environment between two interpreters:
- The master interpreter is created when Woof! is started and is privileges to execute all Tcl commands. The master interpreter reads the configuration, initializes web server interfaces and various subsystems.
- The application interpreter is a safe interpreter. It is created by the master interpreter which also loads most of the Woof! runtime packages into it including the woof package. The master interpreter also creates various aliased commands, such as those for the web server interfaces and logging, in the application interpreter.
When a client request arrives, the master interpreter receives it from the web server and passes it into the safe application interpreter. The application interpreter processes the request and then calls the web server interfaces to return the response to the client.
The advantage of this model of processing is that most of the processing happens in an interpreter whose access to system resources such as the file system is limited. This is by no means a panacea against security vulnerabilities but affords some additional level of protection.
Loading application-specific code in the master interpreter
Because the application interpreter is a safe interpreter, not all
Tcl code, for example database access functions, can be executed in
it directly. Instead, the application must load code in the master
interpreter and then appropriately use the
interp alias
command to make the required commands visible in the application
interpreter.
Application-specific code is loaded in the master interpreter at
start up time. After creation of the application interpreter, the
master checks for the existence of the file
app_master.tcl in the
app subdirectory under the Woof!
root and loads it using the Tcl
source command. This file may in turn load
other packages as well as modify the application interpreter. The
name of the application interpreter can be obtained through the
::woof::master::app_interp
command.
The path app/lib under the Woof! root
directory is automatically added to the auto_path
Tcl
variable. If you are loading packages from other directories, they
should be added to auto_path
as well.
Below is a sample app_master.tcl
file which assumes the presence of a database
package db
and make a single command visible in the
application interpreter.
# File app_master.tcl package require db ;# Load the package ...Initialize the database connections etc... proc select_alias {args} { ...check arguments etc... db::select db_handle {*}$args } # Create a global command db_select in the application interpreter that # will be handled by the the master interpreter [::woof::master::app_interp] alias ::db_select ::select_alias