| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| package require opt 0.4.1; |
|
|
| namespace eval ::safe { |
|
|
| |
| variable tkSafeId 0 |
| } |
|
|
| |
| |
| |
| |
| |
| proc ::safe::tkInterpInit {child argv} { |
| global env tk_library |
|
|
| |
| set tk_library [file normalize $tk_library] |
|
|
| |
| allowTk $child $argv |
|
|
| |
| ::interp eval $child [list set tk_library [::safe::interpAddToAccessPath $child $tk_library]] |
| foreach subdir [::safe::AddSubDirs [list $tk_library]] { |
| ::safe::interpAddToAccessPath $child $subdir |
| } |
| return $child |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
|
|
| |
| proc ::safe::loadTk {} {} |
|
|
| ::tcl::OptProc ::safe::loadTk { |
| {child -interp "name of the child interpreter"} |
| {-use -windowId {} "window Id to use (new toplevel otherwise)"} |
| {-display -displayName {} "display name to use (current one otherwise)"} |
| } { |
| set displayGiven [::tcl::OptProcArgGiven "-display"] |
| if {!$displayGiven} { |
| |
| |
| if {[catch {set display [winfo screen .]}]} { |
| if {[info exists ::env(DISPLAY)]} { |
| set display $::env(DISPLAY) |
| } else { |
| Log $child "no winfo screen . nor env(DISPLAY)" WARNING |
| set display ":0.0" |
| } |
| } |
| } |
|
|
| |
| namespace upvar ::safe S$child state |
|
|
| if {![::tcl::OptProcArgGiven "-use"]} { |
| |
| lassign [tkTopLevel $child $display] w use |
|
|
| |
| |
| set state(cleanupHook) [list tkDelete {} $w] |
| } else { |
| |
| |
| set state(cleanupHook) [list disallowTk] |
|
|
| |
| if {[string match ".*" $use]} { |
| set windowName $use |
| set use [winfo id $windowName] |
| set nDisplay [winfo screen $windowName] |
| } else { |
| |
| |
| |
| |
| if {![catch {winfo pathname $use} name]} { |
| set nDisplay [winfo screen $name] |
| } else { |
| |
| set nDisplay $display |
| } |
| } |
| if {$nDisplay ne $display} { |
| if {$displayGiven} { |
| return -code error -errorcode {TK DISPLAY SAFE} \ |
| "conflicting -display $display and -use $use -> $nDisplay" |
| } else { |
| set display $nDisplay |
| } |
| } |
| } |
|
|
| |
| tkInterpInit $child [list "-use" $use "-display" $display] |
|
|
| load {} Tk $child |
|
|
| return $child |
| } |
|
|
| proc ::safe::TkInit {interpPath} { |
| variable tkInit |
| if {[info exists tkInit($interpPath)]} { |
| set value $tkInit($interpPath) |
| Log $interpPath "TkInit called, returning \"$value\"" NOTICE |
| return $value |
| } else { |
| Log $interpPath "TkInit called for interp with clearance:\ |
| preventing Tk init" ERROR |
| return -code error -errorcode {TK SAFE PERMISSION} "not allowed" |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc ::safe::allowTk {interpPath argv} { |
| variable tkInit |
| set tkInit($interpPath) $argv |
| return |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc ::safe::disallowTk {interpPath} { |
| variable tkInit |
| |
| if {[info exists tkInit($interpPath)]} { |
| unset tkInit($interpPath) |
| } |
| return |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| proc ::safe::tkDelete {W window child} { |
|
|
| |
| |
|
|
| Log $child "Called tkDelete $W $window" NOTICE |
| if {[::interp exists $child]} { |
| if {[catch {::safe::interpDelete $child} msg]} { |
| Log $child "Deletion error : $msg" |
| } |
| } |
| if {[winfo exists $window]} { |
| Log $child "Destroy toplevel $window" NOTICE |
| destroy $window |
| } |
|
|
| |
| disallowTk $child |
| return |
| } |
|
|
| proc ::safe::tkTopLevel {child display} { |
| variable tkSafeId |
| incr tkSafeId |
| set w ".safe$tkSafeId" |
| if {[catch {toplevel $w -screen $display -class SafeTk} msg]} { |
| return -code error -errorcode {TK TOPLEVEL SAFE} \ |
| "Unable to create toplevel for \"$child\" ($msg)" |
| } |
| Log $child "New toplevel $w" NOTICE |
|
|
| set msg "Untrusted Tcl applet ($child)" |
| wm title $w $msg |
|
|
| |
| ttk::style layout TWarningFrame {WarningFrame.border -sticky nswe} |
| ttk::style configure TWarningFrame -background red |
|
|
| set wc $w.fc |
| ttk::frame $wc -relief ridge -borderwidth 4 -style TWarningFrame |
|
|
| |
| bindtags $wc [concat Safe$wc [bindtags $wc]] |
| bind Safe$wc <Destroy> [list ::safe::tkDelete %W $w $child] |
|
|
| ttk::label $wc.l -text $msg -anchor w |
|
|
| |
| |
|
|
| |
| |
| ttk::frame $wc.fb -borderwidth 0 |
| ttk::button $wc.fb.b -text "Delete" \ |
| -command [list ::safe::tkDelete $w $w $child] |
| pack $wc.fb.b -side right -fill both |
| pack $wc.fb -side right -fill both -expand 1 |
| pack $wc.l -side left -fill both -expand 1 -ipady 2 |
| pack $wc -side bottom -fill x |
|
|
| |
| frame $w.c -container 1 |
| pack $w.c -fill both -expand 1 |
|
|
| |
| list $w [winfo id $w.c] |
| } |
|
|