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.