TIP: 120 Title: Restricted DDE Services Version: $Revision: 1.5 $ Author: Pat Thoyts 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.