1 ############################################################
3 # Copyright (C) 1998 William F. Schelter #
4 # For distribution under GNU public License. See COPYING. #
6 # Time-stamp: "2024-03-25 21:13:36 villate" #
7 ############################################################
9 ## the following worked to have an entry box that spoke...
10 # % safe::interpCreate jack
14 # % safe::interpInit $slave
16 # % interp eval $slave set env(DISPLAY) $env(DISPLAY)
19 # % interp eval jack {entry .ja ; pack .ja}
20 # % interp eval $slave { proc policy {args } {} }
21 # % Safesock_PolicyInit $slave
22 # % setupUnknown $slave
23 # % setupPrintVariables $slave
24 # % interp eval jack plot2d -xfun {sin(x)}
26 proc makeEmbedWin
{ parent width height
} {
27 global maxima_priv env auto_index
28 set win
$parent.embed
[incr maxima_priv
(counter
)]
29 set fr
[frame $win -width $width -height $height -container 1]
30 set slave tclet
$maxima_priv(counter
)
31 safe
::interpCreate $slave
32 # make it exist somehow the autoload stuff doesn't make it a command
33 if { [info exists auto_index
(::safe::allowTk) ] } {
34 ::safe::allowTk $slave [list -use [winfo id
$fr]]
36 ::safe::tkInterpInit $slave [list -use [winfo id
$fr]]
37 interp eval $slave [list set argv
[list -use [winfo id
$fr]]]
39 safe
::interpInit $slave
40 interp eval $slave [list set argv
[list -use [winfo id
$fr]]]
43 if { [info exists env
(DISPLAY
)] } {
44 interp eval $slave set env
(DISPLAY
) $env(DISPLAY
)
46 interp eval $slave { proc policy
{args
} {} }
47 # $slave alias bgerror bgerror
49 Safesock_PolicyInit
$slave
51 setupPrintVariables
$slave
56 proc setupUnknown
{ slave
} {
57 interp eval $slave {rename auto_load auto_load-orig
}
58 interp alias
$slave auto_load1
{} auto_load1
$slave
59 interp eval $slave { proc auto_load {args
} {
60 if { [eval auto_load1
$args] } { return 1 }
61 uplevel 1 auto_load-orig
$args
66 proc auto_load1
{ slave name
{namespace ""} } {
67 if { "[info proc $name ]" != "" } {
68 set arglist
[info args
$name]
71 if { [info default $name $v theDefault
] } {
72 lappend theargs
[list $v $theDefault]
77 interp eval $slave [list proc $name $theargs [info body
$name]]
83 proc setupPrintVariables
{ slave
} {
84 global printOption fontSize show_balloons getOp parse_table Parser
\
85 axisGray plot2dOptions plot3dOptions paperSizes printOptions
\
86 doExit fontCourier8 plotdfOptions maxima_priv
87 foreach v
{printOption fontSize show_balloons getOp parse_table Parser
88 axisGray plot2dOptions plot3dOptions paperSizes printOptions
89 doExit fontCourier8 plotdfOptions maxima_priv
} {
90 if { [array exists
$v] } {
91 interp eval $slave [list array set $v [array get
$v *] ]
92 } else {interp eval $slave [list set $v [set $v ]]}}}
94 if { "[info command policy]" != "policy" } {proc policy
{ args
} { }}
96 ## source nsafesock.tcl
98 ###### nsafesock.tcl ######
99 # The Safesock Security Policy.
100 # -----------------------------
102 # Author: Jacob Levy & Brent Welch, 3/10/97
104 # This policy allows a safe slave to connect to remote sockets under the
105 # control of a master. The URL from which the applet is classified as
106 # either "inside" or "outside" and the host is added to the set of "inside"
107 # and "outside" hosts that this Tclet is allowed to connect to. Then, on
108 # the first request to connect to a host, if the host is classified as
109 # "inside" then subsequently the Tclet is allowed to connect only to hosts
110 # that are classified as "inside" (the same for if the first attempt is to
111 # connect to a host classified as "outside").
113 # The arrays used to drive this policy are defined in safesock.data.
115 # Remember the location of the data file for the Safesock policy, so that
116 # it can be reloaded each time the policy is used, to reflect changes.
118 global safesockDataFile
119 set safesockDataFile
[file join [file dirname
[info script
]] safesock.data
]
121 proc Safesock_PolicyInit
{slave
{version
1.0}} {
122 global browser_state
;# Browser state
123 global safesock_inside safesock_outside
125 interp alias
$slave socket {} SafesockSocketAlias
$slave
126 interp alias
$slave fconfigure {} SafesockFconfigureAlias
$slave
128 uplevel "#0" {source $safesockDataFile}
131 # Attempt to get the URL and extract the server and port portions:
133 set server
"" ; set port
"" ; set url
""
134 catch {set url
$browser_state($slave,url
)}
135 if {[regexp -nocase {http://([^
:/]+)(:([0-9]+))?
/} $url \
137 if {[string length
$port] == 0} {
140 set server
[string tolower
$server]
141 } elseif
{[string match
"file:*" $url]} {
146 # At this time it is unknown whether the slave will use inside
147 # or outside connections:
149 set browser_state
($slave,safesock
,permissions
) unknown
151 # Save the homebase for this Tclet:
152 set browser_state
($slave,safesock
,homebase
) $server
154 # Tell the slave about itself:
155 interp eval $slave [list set env
(SERVER
) $server]
156 interp eval $slave [list set env
(PORT
) $port]
157 interp eval $slave [list set env
(URL
) $url]
159 browser_log
$slave security installed policy Safesock
162 proc SafesockDecideInsideOrOutside
{slave server
} {
163 global safesock_insideExclude safesock_outsideExclude
164 global safesock_inside safesock_outside
168 # If the server matches anything outside and nothing in the outside
169 # exclusion list, then it's outside:
171 foreach i
[array names safesock_outside
] {
172 if {[string match
$i $server]} {
178 if {"$status" == "outside"} {
179 foreach i
[array names safesock_outsideExclude
] {
180 if {[string match
$i $server]} {
187 # If the status is unknown, check whether it might be inside. It is
188 # inside if the server matches anything inside and nothing in the
189 # inside exclusion list:
191 if {"$status" == "unknown"} {
192 foreach i
[array names safesock_inside
] {
193 if {[string match
$i $server]} {
199 if {"$status" == "inside"} {
200 foreach i
[array names safesock_insideExclude
] {
201 if {[string match
$i $server]} {
209 # If the status is unknown at this point, raise an error
211 if {"$status" == "unknown"} {
212 error [concat [mc
"unknown host:"] "$server"]
218 # This procedure is invoked when the slave is destroyed to clean up
219 # any associated state. It frees up the array of hosts and ports that
220 # the slave is allowed to connect to:
222 proc Safesock_PolicyCleanup
{slave
} {
225 foreach i
[array names browser_state
$slave,safesock
,*] {
226 unset browser_state
($i)
232 #-----------------------------------------------------------------
234 # SafesockServerAnswer -- will replace COMMAND in a `socket -server command'
235 # request. Checks if the incoming connection is allowed and if so
236 # invokes the original command. Allowed is based on the same criteria
237 # as the outgoing connection.
241 # Side Effects: if connect is allowed, transfer the socket to the slave
242 # and eval the original command there.
244 #----------------------------------------------------------------
246 proc SafesockServerAnswer
{ slave command sock host port
} {
247 set peer
[fconfigure $sock -peername]
248 set host
[lindex $peer 1]
249 set host
[string tolower
$host]
250 if { [SafesockAllow
$slave $host [lindex $peer 2]] > 0 } {
251 interp transfer
{} $sock $slave
252 interp eval $slave $command $sock $host $port
254 interp eval $slave [list error [mc
"connection from %s and %s disallowed" $host $port] ]
261 #-----------------------------------------------------------------
263 # SafesockAllow -- check if connection by SLAVE to HOST at PORT is allowed,
264 # based on the inside/outside history of slave and data in safesock.data
266 # Results: 1 if succeeds and 0 if it fails to allow
268 # Side Effects: set GOOD to ok port in the caller
270 #----------------------------------------------------------------
272 proc SafesockAllow
{ slave host port
} {
274 global safesock_insideExclude safesock_outsideExclude
275 global safesock_inside safesock_outside
277 set host
[string tolower
$host]
278 if {"$browser_state($slave,safesock,permissions)" == "unknown"} {
279 if {[catch {set this
[SafesockDecideInsideOrOutside
$slave $host]}]} {
280 if {"$host" == "$browser_state($slave,safesock,homebase)"} {
283 error [concat [mc
"unknown host:"] "$host"]
286 set browser_state
($slave,safesock
,permissions
) $this
287 browser_log
$slave security
$slave classified as
$this
291 if {"$browser_state($slave,safesock,permissions)" == "homebase"} {
292 if {"$host" == "$browser_state($slave,safesock,homebase)"} {
293 set portset
$browser_state($slave,safesock
,homeport
)
295 } elseif
{"$browser_state($slave,safesock,permissions)" == "inside"} {
296 foreach hostpat
[array names safesock_inside
] {
297 if {[string match
$hostpat $host]} {
298 set portset
$safesock_inside($hostpat)
302 if {"$portset" != "-"} {
303 foreach hostpat
[array names safesock_insideExclude
] {
304 if {[string match
$hostpat $host]} {
311 foreach hostpat
[array names safesock_outside
] {
312 if {[string match
$hostpat $host]} {
313 set portset
$safesock_outside($hostpat)
317 if {"$portset" != "-"} {
318 foreach hostpat
[array names safesock_outsideExclude
] {
319 if {[string match
$hostpat $host]} {
327 if {"$portset" == "-"} {
328 error [concat [mc
"unknown host:"] "$host"]
331 if { [safesockPortMatches
$port $portset] } {
338 proc safesockPortMatches
{ port portset
} {
339 foreach portspec
$portset {
340 set low
[set high
""]
341 if {[regexp {^
([0-9]+)-([0-9]*)$} $portspec x low high
]} {
342 if {($low <= $port && $high == "") ||
343 ($low <= $port && $high >= $port)} {
347 } elseif
{$port == $portspec} {
354 # the following should be set in safesock.data
355 global safesockAllowedServerPorts
356 if { ![info exists safesockAllowedServerPorts
] } {
357 set safesockAllowedServerPorts
{ 1025-3000 }
360 proc SafesockSocketAlias
{slave host port args
} {
361 global safesockAllowedServerPorts
363 if { "$host" == "-server" } {
365 set port
[lindex $args 0]
366 if { ![safesockPortMatches
$port $safesockAllowedServerPorts] } {
367 error [concat [mc
"bad port:"] "$port"]
369 set sock
[socket -server \
370 "SafesockServerAnswer $slave [list $command]" $port]
371 interp transfer
{} $sock $slave
372 browser_log
$slave normal
socket -server $port
374 } elseif
{ "$host" == "-async" } {
377 set port
[lindex $args 0]
379 if { [llength $args ] != 0 } {
380 error [mc
"wrong args: socket host port OR socket -server command port"]
384 SafesockAllow
$slave $host $port
385 if [info exists good
] {
386 if { "$option" != "" } {
387 set sock
[interp invokehidden
$slave socket $option $host $good]
389 set sock
[interp invokehidden
$slave socket $host $good]
391 browser_log
$slave normal
socket $host $port
394 error [concat [mc
"bad port:"] "$port"]
397 # This procedure handles the "fconfigure" alias from the slave:
399 proc SafesockFconfigureAlias
{slave sock args
} {
401 if {[llength $args] == 0} {
402 return [interp invokehidden
$slave fconfigure $sock]
403 } elseif
{[llength $args] == 1} {
404 set flag
[lindex $args 0]
405 return [interp invokehidden
$slave fconfigure $sock $flag]
407 browser_log
$slave normal
fconfigure $sock $args
409 array set config
[interp invokehidden
$slave fconfigure $sock]
410 foreach {flag value
} $args {
414 error [concat [mc
"Cannot change"] "$flag configuration"]]
421 set config
($flag) $value
424 error [concat [mc
"unknown option"] "$flag"]
428 lappend jack
[list interp invokehidden
$slave fconfigure $sock \
429 -blocking $config(-blocking) \
430 -buffering $config(-buffering) \
431 -buffersize $config(-buffersize) \
432 -eofchar $config(-eofchar) \
433 -translation $config(-translation)]
434 return [interp invokehidden
$slave fconfigure $sock \
435 -blocking $config(-blocking) \
436 -buffering $config(-buffering) \
437 -buffersize $config(-buffersize) \
438 -eofchar $config(-eofchar) \
439 -translation $config(-translation)]
443 ## endsource nsafesock.tcl
446 ## endsource tryembed.tcl