safe(3tcl)

NAME
Safe - 用來建立和操縱安全直譯器的機制。

總覽 SYNOPSIS
::safe::interpCreate ?slave? ?options...?

::safe::interpInit slave ?options...?

::safe::interpConfigure slave ?options...?

::safe::interpDelete slave

::safe::interpAddToAccessPath slave directory

::safe::interpFindInAccessPath slave directory

::safe::setLogCmd ?cmd arg...?

OPTIONS

?-accessPath pathList? ?-statics boolean? ?-noStatics? ?-nested boolean? ?-nestedLoadOk? ?-deleteHook script?

描述 DESCRIPTION
Safe Tcl 是一種機制，用於安全的執行不可信任的 Tcl 指令碼，併為有潛在危險功能的指令碼提供訪問中介。

Safe Base 確保不可信任的 Tcl 指令碼不能損壞宿主應用。Safe Base 防止完整性和隱私攻擊。防止不可信任的 Tcl 指令碼敗壞宿主應用或計算機的狀況。防止不可信任的指令碼把儲存在宿主主機或宿主應用中的資訊洩露給任何人群。

Safe Base 允許一個主直譯器建立安全、受限制的直譯器，它包括為 source, load, file, encoding, 和 exit 命令預定義的一系列別名，並可以使用自動裝載和包機制。

不向安全直譯器透露檔案系統的任何東西，它只能訪問包含記號(token)的虛擬的路徑。當安全直譯器請求 source(載入)一個檔案的時候，它使用在虛擬路徑中的記號作為要 source 的檔名的一部分；主直譯器透明的把這個記號轉換成一個實際的路徑名並執行所要求的操作 (詳情參見下面的 SECURITY 安全 章節). 可以使用下面描述的命令標誌來選擇不同的安全級別。

Safe Base 在主直譯器中提供的所有命令駐留在 safe 名字空間中:

命令 COMMANDS
在主直譯器中提供了下列命令:

::safe::interpCreate ?slave? ?options...?
    建立一個安全直譯器，安裝在ALIASES 別名 章節中描述的別名並初始化在 OPTIONS 選項 中提供的自動裝載和包機制。對可選擇的引數的描述請參見下面 OPTIONS 選項 章節。如果省略了slave 引數，則生成一個名字。::safe::interpCreate 總是返回直譯器的名字。

::safe::interpInit slave ?options...?
    除了不建立安全直譯器之外，這個命令類似於 interpCreate 命令。必須已經透過其他方式如 interp create -safe建立了這個 slave。

如果未給出 options，則把給指名的這個直譯器所有選項的設定返回為給這個 slave 的選項和它們當前的值的一個列表。如果提供了一個單一的補充引數，它將返回有兩個元素 name 和 value 的一個列表，這裡的 name 是選項的全名而 value 是給 slave 的這個選項當前值。如果提供多於兩個補充選項，它將重新配置這個安全直譯器並只改變每個提供的選項。關於選項的描述請參見下面的 OPTIONS 章節。使用的例子:
    # Create a new interp with the same configuration as "$i0" : set i1 [eval safe::interpCreate [safe::interpConfigure $i0]] # Get the current deleteHook set dh [safe::interpConfigure $i0 -del] # Change (only) the statics loading ok attribute of an interp # and its deleteHook (leaving the rest unchanged) : safe::interpConfigure $i0 -delete {foo bar} -statics 0 ;

::safe::interpDelete slave
    刪除這個安全直譯器並清除相應的主直譯器資料結構。如果為這個直譯器指定了一個 deleteHook 指令碼，則在刪除這個直譯器之前執行這個指令碼，把這個直譯器的名字作為一個補充引數。

::safe::interpFindInAccessPath slave directory
    這個命令尋找並返回在安全直譯器的當前虛擬訪問路徑中給實際路徑 directory 的記號。如果未找到這個路徑則生成一個錯誤。使用的例子:
    $slave eval [list set tk_library [::safe::interpFindInAccessPath $name $tk_library]]

::safe::interpAddToAccessPath slave directory
    這個命令把 directory 新增到在主直譯器中為安全直譯器維護的虛擬路徑中，並返回可在安全直譯器中被用來獲得到在這個目錄中的檔案的訪問的記號。如果這個路徑已經存在於虛擬路徑中，則它只返回記號而不再次把這個路徑新增到虛擬路徑中。使用的例子:
    $slave eval [list set tk_library [::safe::interpAddToAccessPath $name $tk_library]]

::safe::setLogCmd ?cmd arg...?
    這個命令安裝在一個指令碼，在這個安全直譯器的特定的生命週期事件發生的時候將被呼叫。在呼叫這個命令而不加引數時，它返回當前安裝的指令碼。在呼叫並加一個引數空串時，則刪除當前安裝的指令碼並關閉日誌記錄。呼叫這個指令碼時將加上一個補充引數，它描述所感興趣的事件。主要的目的是幫助除錯安全直譯器。在安全直譯器只能得到一個一般錯誤訊息的時候你可以使用這個設施獲得完整的錯誤訊息。這防止安全直譯器見到關於失敗的訊息和其他可能包含敏感資訊如真實路徑名的其他事件的訊息。
    使用的例子: ::safe::setLogCmd puts stderr 下面是一個樣本對話的輸出，這裡一個安全直譯器嘗試著 source 一個在它的虛擬 訪問路徑中找不到的檔案。注意這個安全直譯器只接收到一個錯誤訊息，說這個文 件未找到:
    NOTICE for slave interp10 : Created
    NOTICE for slave interp10 : Setting accessPath=(/foo/bar) staticsok=1 nestedok=0 deletehook=()
    NOTICE for slave interp10 : auto_path in interp10 has been set to {$p(:0:)}
    ERROR for slave interp10 : /foo/bar/init.tcl: no such file or directory

選項 OPTIONS
下列選項通用於 ::safe::interpCreate、::safe::interpInit、和 ::safe::interpConfigure。任何選項都可縮寫為它的最小的無歧義的名字。選項的名字是大小寫不敏感的。

-accessPath directoryList
    這個選項設定目錄的列表，安全直譯器可以從中 source 和 load 檔案。如果未指定這個選項，或者它被給定為一個空列表，安全直譯器將使用的目錄同與它的主直譯器用於自動裝載的目錄。關於虛擬路徑、記號和訪問控制的詳情請參見下面的 SECURITY 安全 章節。

-statics boolean
    這個選項指定是否允許這個安全直譯器裝載靜態連線包(如 load {} Tk)。預設值是 true : 允許安全直譯器裝載靜態連線包。

-noStatics
    這個選項是 -statics false 的一個方便的簡寫，它指定不允許這個安全直譯器裝載靜態連線包。

-nested boolean
    這個選項指定是否允許這個安全直譯器把包裝載到它自己的子直譯器中。預設值是 false : 不允許安全直譯器把包裝載到它自己的子直譯器中。

-nestedLoadOk
    這個選項是 -nested true 的一個方便的簡寫，它指定允許安全直譯器把包裝載到它自己的子直譯器中。

-deleteHook script
    當給這個選項以一個非空的 script 的時候，它將在實際刪除這個從直譯器之前在主直譯器中被求值，並加上這個安全直譯器的名字作為一個補充的引數。給予一個空值則去除任何當前為這個安全直譯器安裝的刪除回撥(hook)指令碼。預設值({})是沒有任何刪除回撥指令碼。

別名 ALIASES
在安全直譯器中提供了下列別名:

source fileName
    如果找到了要求的這個 Tcl 原始檔，則把它 source(裝載)到安全直譯器中。 source 別名只可以從給這個安全直譯器的虛擬路徑中的目錄 source 檔案。 關於在有效檔名上的限制的更多資訊請參見 SECURITY 安全 章節。

load fileName
    如果找到了要求的這個共享的目標檔案，則把它動態的裝載到安全直譯器中。為了能成功的找到它，檔名必須包含在給這個安全直譯器的虛擬路徑中提及的一個記號的名字。還有，這個共享的目標檔案必須包含一個安全入口點；詳情請參見 load 命令的手冊條目。

file ?subCmd args...?
    file 別名提供到 file命令的子命令的一個安全子集的訪問；它只允許 dirname、join、 extension、root、tail、pathname 和 split 子命令。關於這些子命令的詳情請參見 file 命令的手冊條目。

encoding ?subCmd args...?
    enconding 別名提供到 encoding 命令的子命令的一個安全子集的訪問；它不允許設定系統編碼，不允許其他子命令包括 system 檢查當前編碼。

exit
    刪除呼叫它的指令碼並停止它的計算，但這個直譯器存在於其中的那個 Tcl 程序不被終止。

安全 SECURITY
Safe Base 不嘗試完全的防止煩惱(annoyance)和拒絕服務攻擊。這些形式的攻擊妨礙應用或使用者臨時的使用計算機來完成有用的工作，例如消耗所有可利用的 CPU 時間或所有可利用的螢幕 real estate。這些攻擊儘管很惡劣，但一般不如 Safe Base 主要防護的完整性和隱私攻擊那麼重要。

除了在 interp 手冊頁中定義的安全命令集之外，在安全直譯器中可獲得的命令還包括給 source、load、exit 的作為中介的(mediate)別名以及 file 和 encoding 命令的安全子集。安全直譯器還可以自動裝載程式碼並可以請求裝載包。

因為這些命令中的一些命令訪問本地檔案系統，存在著對它的目錄結構的潛在的資訊洩露。為了防止這個問題，接受檔名作為引數的命令在安全直譯器中使用記號來替代真實的目錄名。在主直譯器中介一個要求例如 source 一個檔案的時候，把這些記號轉換成實際路徑名。在主直譯器中維護這個虛擬路徑系統，針對每個用 ::safe::interpCreate 建立的或用 ::safe::interpInit 初始化的安全直譯器，這個路徑把在安全直譯器中可訪問的記號對映成在本地檔案系統上的真實路徑名，這樣就防止了安全直譯器去獲取關於這個直譯器在其上執行的主機的檔案系統結構的知識。可以提供給從直譯器中的 source 和 load 別名的有效的檔名引數只能是下面這種形式的路徑： [file join token filename] (比如，在使用本地檔案路徑格式的時候: 在 Unix 上是 token/filename，在 Windows 上是 token\filename，在 Mac 上是 token:filename )，這裡的 token 表示 accessPath 列表中的一個目錄而 filename 是在這個目錄中一個檔案(不允許訪問子目錄)。

在一個安全直譯器中，當在要 source 或裝載一個檔案的一個請求中使用一個記號的時候，檢查這個記號並把它轉換成真實路徑名，並在檔案系統上定位要被 source 或裝載的檔案。安全直譯器不能獲取關於檔案系統上在其下儲存這個檔案的實際路徑名的知識。

為了進一步防止潛在的對偶然的包括在可以被安全直譯器 source 的檔案集中的敏 感檔案的資訊洩露，限制 source 別名為訪問滿足下列約束的檔案: 檔名 必須是十四個字元或更短，必須不包含多於一個的點(“.”)，不許終止於擴 展 .tcl 或是被呼叫的 tclIndex。

初始的訪問路徑列表中的每個元素將分配一個記號，它們將被設定在從直譯器的 auto_path 中並且這個列表的第一個元素將被設定為這個從直譯器的 tcl_library。

如果未給出訪問路徑引數或者是一個空列表，預設的行為是讓從直譯器訪問的包與主直譯器已經訪問了的包相同(更精確的描述: 只允許用 Tcl 寫成的包(因為它們將在從直譯器中執行所以不可能是危險的)和提供 Safe_Init 入口點的 C 擴充套件)。為此，用主直譯器的 auto_path 來構造從直譯器的訪問路徑。為了從直譯器能成功的裝載 Tcl 庫檔案(它自身包括自動裝載機制)，如果需要的話，把 tcl_library 增加或移動到在從直譯器的訪問路徑中的第一個的位置上，這樣從直譯器的 tcl_library 將與主直譯器的相同(它的真實路徑對從直譯器仍是不可見的)。為了使自動裝載對於從直譯器和主直譯器在預設的情況下以相同的方式工作，在主直譯器 auto_path 中的每個目錄的第一層子目錄將被新增(如果未曾包含的話)到從直譯器的訪問路徑中。你總是可以透過顯式的使用 -accessPath 標誌指定你的目錄列表，而不是依賴於這個預設機制，來指定一個更受限制的路徑，它的子目錄永遠不能被查詢。

在首次建立或初始化(例如透過 interpConfigure -accessPath list)之後變更 accessPath 的時候，將在安全直譯器中自動的求值 auto_reset 來使它的 auto_index 與新的記號列表同步。

參見 SEE ALSO
interp(n), library(n), load(n), package(n), source(n), unknown(n)

關鍵字 KEYWORDS
alias, auto-loading, auto_mkindex, load, master interpreter, safe interpreter, slave interpreter, source

[中文版維護人]
寒蟬退士

[中文版最新更新]
2001/11/07

《中國 Linux 論壇 man 手冊頁翻譯計劃》:
http://cmpp.linuxforum.net

跋
本頁面中文版由中文 man 手冊頁計劃提供。
中文 man 手冊頁計劃：https://github.com/man-pages-zh/manpages-zh