TIP 120: Restricted DDE Services

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Author:         Pat Thoyts <patthoyts@users.sourceforge.net>
State:          Final
Type:           Project
Vote:           Done
Created:        04-Dec-2002
Post-History:   
Tcl-Version:    8.5

Abstract

This TIP will enhance the DDE package for use with safe interpreters and allow programmer control of the commands exposed by the DDE service.

Rationale

By default the Tcl DDE service exposes all of the commands and variables available in the interpreter to all DDE clients. This is not always desirable. One solution might be to load the package into a safe slave interpreter and use [interp alias] to expose the required commands. Unfortunately the package doesn't support loading into safe interpreters.

Proposed Changes

Firstly, this TIP proposes a -handler option to the [dde servername] sub-command. The argument for this option should be the name of a procedure that will authenticate and evaluate DDE requests.

Secondly, the DDE package should be enhanced to be capable of providing a service within a safe interpreter.

New Option

The new syntax will be dde servername ?-handler command? servername. To permit introspection we will accept dde servername -handler which will return the handler name (if any). If a servername must be defined using an initial hyphen then the standard '--' separator can be used.

The dde request is appended to the handler command (which may be a list) and then evaluated in the global context. This ensures that all unsafe elements will not be evaluated before the handler code has a chance to examine them. So

 proc handler {request} {
    if {[string match "info *" $request} {
       uplevel #0 [lindex $request 0] [lrange $request 1 end]
    } else
       return -code error "permission denied"
    }
 }

The above handler will permit [info vars] but will fail when trying [info vars ; bad_proc] with info complaining about the wrong number of parameters. Passing a single string means that we can handle standard dde styles of requests, for instance 'Open("c:\Program Files\prog.exe")' which would not usefully convert into a list.

Safe DDE

The dde package should support loading within a safe interpreter but with the following constraints.

  • The dde command should be hidden. This means that the safe interpreter may not call the command but a master interpreter call this command within the context of the safe interpreter.

  • Remote execution requests should be handled only by a defined handler procedure. The normal default is to evaluate a remote execution request in the global namespace. I propose that when operating in a safe interpreter that the request be denied unless a handler is defined. The programmer then has the ability to authenticate the request before it is evaluated.

  • Remote variable reads should be denied. Rather that add in another handler - the XTYP_REQUEST service command should be denied for safe interpreters. It is trivial to use [dde eval Remote set $varname] to read the value of a variable.

Reference Implementation

See the SourceForge Feature Request at https://sourceforge.net/tracker/index.php?func=detail&aid=649859&group\_id=10894&atid=310894

Example

 # Provide a handler that only allows the [info] command
 # Note: This runs in the master interp.
 proc restricted_handler {request} {
    if {[string match "info *" $request} {
       uplevel #0 [lindex $request 0] [lrange $request 1 end]
    } else
       return -code error "permission denied"
    }
 }

 # Create a safe slave interpreter and expose as a DDE service.
 safe::interpCreate slave
 slave invokehidden load tcldde12d.dll Dde
 slave invokehidden dde servername -handler dde_cmd SafeSlave
 interp alias slave dde_cmd {} restricted_handler

 # If testing in tclsh...
 set ::_waiting 0 ; after 20000 {set ::_waiting 1} ; vwait ::_waiting

Consequences

There should be no change to current users of this package unless they are using a server name beginning with a hyphen. In this case they will need to insert '--' before the server name.

Copyright

This document is hereby placed in the public domain.

History