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

48

# 48 Safe-Tk and
the Browser Plug-In

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.

    http://sunscript.sun.com/tcl/plugin/

    http://sunscript.sun.com/tcl/plugintut/

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:

    http://www.beedub.com/plugin/bike.html

### 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:

- The plug-in shared libraries (i.e., DLLs). The Web browser dynamically loads the plug-in implementation when it needs to execute a Tclet embedded in a Web page. There is a standard directory that the browser scans for the libraries that implement plug-ins.
- The Tcl/Tk script libraries. The plug-in needs the standard script libraries that come with Tcl and Tk, plus it has its own scripts that complete its implementation. Each platform has a plug-in script directory with these subdirectories: tcl8.0, tk8.0, plugin, policies, and trust. The plug-in implementation is in the plugin directory.
- The security policies. These are kept in a policies directory that is a peer of the Tcl script library.
- The trust map. This defines what Tclets can use which security policies. This is in a trust directory that is a peer of the Tcl script library.
- Local hooks. Local customization is supported by two hooks, siteInit and siteSafeInit. The siteInit procedure is called from the plug-in when it first loads, and siteSafeInit is called when each applet is initialized. It is called with the name of the slave interpreter and the list of arguments from the <EMBED> tag. You can provide these as scripts that get loaded from the auto_path of the master interpreter. Chapter 12 describes how to manage script libraries found in the auto_path. The plug-in also sources a personal start up script in which you can define siteInit and siteSafeInit. This script is ~/.pluginrc on UNIX and plugin/tclplugin.rc on Windows and Macintosh.
The plug-in is configured to use wish instead of linking Tk into the Web browser. This only works on UNIX and Windows. You can define the TCL_PLUGIN_WISH environment variable to be the pathname of the executable wish. It must be a Tk 8.0 or greater version of wish, which supports embedding. There are two advantages to using wish. First, it means the embedded Tcl application runs in a separate process from the Web browser, which can be more efficient. Second, it allows for custom wish applications that have extensions built in or dynamically loaded. If you want to run Tk directly in the browser process, define the TCL_PLUGIN_INPROCESS variable to 1.

If you set the TCL_PLUGIN_CONSOLE environment variable to 1, then a console window is opened when a Tclet starts. This console lets you evaluate Tcl commands in the master interpreter. In particular, if you do interp slaves you can find out the names of the safe interpreters used for Tclets. You can use other facilities of the interp command to examine and manipulate the Tclets. The interp command is described on page 204. If the value of TCL_PLUGIN_CONSOLE is something else, it is treated as a file name and that file is sourced in order to define the console.

### 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.

- home. This provides a socket and fconfigure command that are limited to connecting to the host from which the Tclet was downloaded. You can specify an empty string for the host argument to socket to connect back to the home host. This policy also supports open and file delete that are similar to the Tempfile policy shown in Example 17-9 on page 216. This provides limited local storage that is inside a directory that is, by default, private to the Tclet. Files in the private directory persist after the Tclet exits, so it can maintain long term state. Tclets from the same server can share the directory by putting the same prefix=partialurl argument in their <EMBED> tag. The partialurl must be a prefix of the Tclet's URL. Finally, the home policy automatically provides a browser package that is described later.
- inside. This is just like the home policy, except the site administrator controls a table of hosts and ports to which untrusted slaves can connect with socket. A similar set of tables control what URLs can be accessed with the browser package. This is similar to the Safesock policy is shown in Example 17-8 on page 214. The set of hosts is supposed to be inside the firewall. The files used by this policy are distinct from those used by the home and outside policies. This is true even if Tclets try to share by using the prefix=partialurl parameter.
- outside. This is just like the home and inside policies, except that the set of hosts is configured to be outside the firewall. The files used by this policy are distinct from those used by the home and inside policies.
- trusted. This policy restores all features of Tcl and Tk. This policy lets you launch all your Tcl and Tk applications from the Web browser. The default trust map settings do not allow this for any Tclet. The trust map is described briefly on page 612.
- javascript. This policy provides a superset of the browser package that lets you invoke arbitrary Javascript and to write HTML directly to frames. This does not have the limited socket or temporary file access that the home, inside, and outside policies have. However, the javascript policy places no restrictions on the URLs you can fetch, plus it lets Tclets execute Javascript, which may have its own security risks. The default trust map settings do not allow this for any Tclet.

### 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.

## Notes

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:

    http://sunscript.sun.com/tcl/plugin/

    http://www.beedub.com/plugin/

[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