[Top] [Prev] [Next] [Bottom]


48 Safe-Tk and
the Browser Plug-In

This chapter describes Safe-Tk that lets untrusted scripts display and manipulate graphical user interfaces. The main application of Safe-Tk is the Tcl/Tk plug-in for Web browsers like Netscape Navigator and Internet Explorer.
Safe-Tk supports network applets that display user interfaces. The main vehicle for Safe-Tk is a plug-in for Netscape Navigator and Internet Explorer. The plug-in supports Tcl applets, or Tclets, that are downloaded from the Web server and execute inside a window in a Web browser. For the most part Tcl/Tk applications can run unchanged in the plug-in. However, security policies place some restrictions on Tclets. The plug-in supports multiple security policies, so Tclets can do a variety of interesting things in a safe manner.

There are two versions of the browser plug-in. Version 1 uses Tcl 7.7 and Tk 4.3, which were not released by themselves. Instead of providing wish and tclsh, only the shared libraries needed by the plug-in were distributed. These versions of Tcl and Tk had support for application embedding and some improvements in Safe-Tcl that later appeared in Tcl/Tk 8.0.

Version 2 of the plug-in uses Tcl/Tk 8.0. You can configure the plug-in to use an existing wish application to host the Tcl applets, or the plug-in can load the Tcl/Tk shared libraries and everything runs in the browser process. You can use a custom wish that has extensions built in or dynamically loaded. This gives intranet applications of the plug-in the ability to access databases and other services that are not provided by the Tcl/Tk core. With the security policy mechanism you can still provide mediated access to these resources. This chapter describes how to set up the plug-in.

Tk in Child Interpreters

A child interpreter starts out with the core Tcl commands. It does not include Tk or any other extensions that might be available to the parent interpreter. This is true whether or not the child interpreter is declared safe. You add extensions to child interpreters by using a form of the load command that specifies an interpreter:

load {} Tk child
Normally, load takes the name of the library file that contains the extension. In this case, the Tk package is a static package that is already linked into the program (e.g., wish or the plug-in), so the file name is the empty string. The load command calls the Tk initialization procedure to register all the Tcl commands provided by Tk.

Embedding Tk Windows

By default, a slave interpreter that loads Tk gets a new top-level window. Tk 8.0 supports a -use command line option that directs Tk to use an existing window as dot. You can use this to embed an application within another, but typically it is used with child interpreters. To pass -use to a child interpreter, you need to define the argv variable inside that interpreter before you load Tk:

interp eval child [list set argv [list -use [winfo id win]]
interp eval child [list set argc 2]
Passing -use to a safe interpreter is handled automatically by the safe::loadTk procedure. If safe::loadTk is not given -use, it adds a wrapper around the slave that is very similar to the one in Example 48-1.

Embedding a Tk window.
# Create a toplevel that indicates it contains an applet
toplevel .embed
frame .embed.but ; pack .embed.but -side top -fill x
label .embed.but.l -text "Untrusted Applet" -anchor w \
	-bg red -fg white
button .embed.but.quit -text Quit \
	-command {::safe::interpDelete safetk}
pack .embed.but.quit -side right
pack .embed.but.l -side top -fill x

# Create the frame in which to embed the applet
set rim [frame .embed.rim -bd 4 -bg red]
pack $rim -fill both -expand true
set embed [frame $rim.child -container true]
pack $embed -fill both -expand true

# Create a safe interpreter and load Tk into it
::safe::interpCreate safetk
::safe::loadTk safetk -use [winfo id $embed]

Safe-Tk Restrictions

When you load an extension into a safe interpreter the extension is initialized with its SafeInit procedure. If there is no SafeInit, then the load fails. The Tk_SafeInit procedure hides several Tk commands. Primarily these are hidden to prevent denial of service attacks against the main process. For example, if a child interpreter did a global grab and never released it, all input would be forever directed to the child. Table 48-1 lists the Tk commands hidden by default from a safe interpreter. The Tcl commands that are hidden are listed on page 207.
Tk commands omitted from safe interpreters.
bell Ring the terminal bell.
clipboard Access the CLIPBOARD selection.
grab Direct input to a specified widget.
menu Create and manipulate menus, because menus need grab.
selection Manipulate the selection.
send Execute a command in another Tk application.
tk Set the application name.
tk_chooseolor Color choice dialog.
tk_getOpenFile File open dialog.
tk_getSaveFile File save dialog.
tk_messageBox Simple dialog boxes.
toplevel Creates a detached window.
wm Control the window manager.

The Browser Plug-In

The HTML <EMBED> tag is used to put various objects into a Web page, including a Tcl program. For example:

<EMBED src=eval.tcl width=400 height=300>
The width and height are interpreted by the plug-in as the size of the embedded window. The src specifies the URL of the program. These parameter names (e.g., width) are case sensitive and should be lowercase. In the above example, eval.tcl is a relative URL, so it should be in the same directory as the HTML file that has the EMBED tag. The window size is fixed in the browser, which is different than normal toplevels in Tk. The plug-in turns off geometry propagation on your main window so your Tclet stays the size allocated.

The parameters in the <EMBED> tag are available to the Tcl program in the embed_args variable, which is an array with the parameter names as the index values. For example, the string for a ticker-tape Tclet can be passed in the <EMBED> tag as the string parameter, and the Tclet will use $embed_args(string) as the value to display:

<EMBED src=ticker.tcl width=400 height=50

string="Hello World">

Note that HTML tag parameters are case sensitive. Your Tclet may want to map all the parameter names to lowercase for convenience:

foreach {name value} [array get embed_args] {

	set embed_args([string tolower $name]) $value

The plugin array has version, patchLevel, and release elements that identify the version and release date of the plugin implementation. Note that version 1.0 of the plug-in does not support security policy mechanism described later, and that the 2.0 version changed substantially between the alpha2 and beta1 releases.

Plug-in example home page.

The plug-in home page is a great place to find Tclet examples. There are several plug-ins done by the Tcl/Tk team at Sunlabs, plus links to a wide variety of Tclets done on the Net. There is also a tutorial page about writing Tclets.

I wrote a cute little plug-in that calculates the effective wheel diameter of multigear bicycles. Brian Lewis explained to me the concept and how important this information is to bicycle enthusiasts. I put together a Tclet that displays the gear combinations on a Tk canvas and lets you change the number of gears and their size. You can find the result at:


Setting Up the Plug-In

There are plug-in versions for UNIX, Windows, and Macintosh. The installation scripts take care of installing the plug-in in the correct locations, which are described in the next sections about each platform. The plug-in and the security policies that are distributed with it will continue to be updated. You should get the latest version from the Tcl/Tk Web site, http://sunscript.sun.com/tcl/plugin/. If that URL changes, you can find an up-to-date pointer under http://www.beedub.com/book/. The plug-in may already be installed at your site. Bring up the About Plug-ins dialog under Help in your browser to see if the Tcl/Tk plug-in is listed.

The plug-in is composed of the following parts, although the location of these files varies somewhat among platforms:

UNIX Configuration

Netscape looks in each user's ~/.netscape/plugins for the shared libraries that implement plug-ins. It also looks in a plugins directory under its main directory, which will vary from site to site. You can define a search path for plug-ins with the NXP_PLUGIN_PATH environment variable. The plug-in script library is in ~/.tclplug/2.0/plugin. You can change this default location by setting the TCL_PLUGIN_DIR environment variable. Once the plug-in finds its script library, it assumes the Tcl and Tk script directories, the security policies, and the trust map are in peer directories.

Windows Configuration

The default location for plug-ins is in the PLUGINS directory of the Netscape installation. The Tcl/Tk plug-in also works in Internet Explorer from the same location. The script libraries are found under C:\TCLPLUG\2.0. You can change this location by setting the registry variable Software\Sun\Tcl Plugin\2.0\Directory.

Macintosh Configuration

As of this writing the Macintosh plug-in is only available in the 1.0 version. The 2.0 version is expected in the next few months.

Security Policies and Browser Plug-in

Version 2 of the plug-in uses the safe base described on page 212. If a Tclet wants a non-default security policy, it requests one with the policy command:

policy name
The policies that are part of the standard plug-in distribution are described below. The home, inside, and outside policies all provide network access. They differ in what set of hosts are accessible.

The Browser Package

The browser package is bundled with several of the security policies. It makes many features of the Web browser accessible to Tclets. They can fetch URLs and display HTML in frames. However, the browser package has some risks associated with it. HTTP requests can be used to transmit information, so a Tclet using the policy could leak sensitive information if it can fetch a URL outside the firewall. To avoid information leakage, the inside, outside, and home policies restrict the URL that can be fetched with browser::geturl. Table 48-2 lists the aliases defined by the browser package.
Aliases defined by the browser package.
browser::status string Display string in the browser status window.
browser::geturl url ?options? Fetch url, if allowed by the security policy. The options are described in Table 48-3.
The remaining functions are only available in the javascript security policy.
browser::openFrame name Open a new or existing HTML frame.
browser::closeFrame name Close the channel to an HTML frame.
browser::writeFrame name html Write HTML to a frame. Writing <p> or <br> causes a flush of data to the page.
browser::javascript script ?callback? Invoke the Javascript script and return the result as a string. The callback is called with two parameters: the script and the results of the script.

The browser::geturl function is compatible with the http::geturl function described on page 198. It returns a token that represents the transaction, and you use that token as the name of a state array as described on page 199. However, browser::geturl uses the browser's built-in functions, so it understands proxies and supports ftp:, http:, and file: urls. In addition, browser::geturl can display the results in a browser frame if you give it a -frame argument. Some options to http::geturl may not be fully supported and browser::geturl will just ignore them. The full set of options are not defined as of this writing. The known options to browser::geturl are described in Table 48-3
Options to the browser::geturl procedure.
-command callback Call callback when the transaction completes. The callback gets the token returned by browser::geturl.
-frame frame Display the url data in the named frame. If frame does not exist, a new top-level browser window is created.
-progress command Call command after each block is copied from url. It gets called with three parameters: the url totalsize currentsize
-query codedstring Issue a POST request with the codedstring form data.

Configuring Security Policies

Each security policy has a configuration file associated with it. For example, the outside policy uses the file outside.cfg file in the policies directory to specify what hosts and ports are accessible to Tclets using the outside policy. For the inside and outside policies, the configuration files are similar in spirit to the safesock array used to configure the Safesock security policy shown on page 214. There are a set of allowed hosts and ports, and a set of excluded hosts. The excluded hosts are an exception list. If a host matches the include set but also matches the exclude set, it is not accessible. There is an include and exclude set for URLs that affect browser::geturl. The settings from the Tempfile policy shown on page 216 are also part of the home, inside, and outside configuration files. The configuration files are well commented, and you should read through them to learn about the configuration options for each security policy.

In addition, there is a permission list, or trust map, that controls what Tclets are allowed to use which security policies. Currently there are just three ways to specify access: no Tclets can use a policy, all Tclets can use a policy, or Tclets whose URL matches an allowed set can use a policy. This map is defined in the trust/trust.cfg file. The URL matching is defined in trust/trustedurl.cfg. Eventually the plug-in will allow certificate based authentication of Tclets so you can restrict security policies based their certificates.


The Web browser plug-in is going to continue to develop and improve, especially in the area of security policies. This chapter reflects the features of the 2.0 beta 1 release, and there will surely be some changes as the plug-in stabilizes. Consult these web pages for news about new releases of the plug-in:


[Top] [Prev] [Next] [Bottom]

Copyright © 1997, Brent Welch. All rights reserved.
This will be published by Prentice Hall as the 2nd Edition of
Practical Programming in Tcl and Tk