# Safe Tcl

Механизм создания и управления безопасными интерпретаторами.

## СИНТАКСИС

          ::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...?

## ОПИСАНИЕ

Safe Tcl - это механизм безопасного исполнения ненадежных Tcl скриптов и предоставления этим скриптам опосредованного доступа к потенциально опасным функциям.

Safe Tcl служит для того, чтобы ненадежные скрипты не смогли нарушить работу вызывающего их приложения: он предотвращает покушения на несанкционированный доступ к информации и нарушение целостности вызывающего этот скрипт процесса.

Safe Tcl позволяет интерпретатору-предку создавать безопасные интерпретаторы с ограниченными возможностями, в которых содержится набор предопределенных синонимов для команд source, load, file и exit и сохраняются возможности автозагрузки команд и пакетов.

Безопасный интерпретатор не позволяет получить какую-либо информацию о структуре файловой системы, поскольку для доступа к файлам в безопасном интерпретаторе используются специальные метки. Когда безопасный интерпретатор запрашивает доступ к файлу, он использует метку как часть виртуального имени файла. Родительский интерпретатор заменяет метку на реальное имя каталога и выполняет требуемую операцию с файлом. С помощью опций команд, описанных ниже, можно выбрать требуемый уровень безопасности интерпретатора.

Все команды для работы с безопасными интерпретаторами содержатся в пространстве имен safe. Команда ::safe::interpCreate создает безопасный интерпретатор. Возможные опции команды описаны ниже, см. "Опции".

Команда возвращает имя созданного интерпретатора. Команда ::safe::interpInit аналогична, но ее первым аргументом должно быть имя интерпретатора, созданного с помощью команды interp. Команда ::safe::interpDelete удаляет интерпретатор, имя которого использовано в качестве аргумента. Команда ::safe::interpConfigure позволяет задать опции для безопасного интерпретатора или получить информацию об заданных ранее опциях. Подробно опции описаны ниже (см. "Опции").

Для каждого безопасного интерпретатора, созданного с помощью команды ::safe::interpCreate или инициированного с помощью команды ::safe::interpInit в родительском интерпретаторе создается список доступных каталогов - виртуальный путь. Каждый каталог в пути связывается с реальным каталогом локальной файловой системы и с меткой, доступной в безопасном интерпретаторе. В результате надежный интерпретатор обходится без сведений о реальной файловой системе на машине, на которой исполняется интерпретатор. Когда в надежном интерпретаторе используется метка для доступа к конкретному файлу (например, для выполнения команды source или load), метка заменяется в родительском интерпретаторе на настоящее имя каталога и необходимый файл ищется в файловой системе. Надежный интерпретатор не получает сведений о реальном имени файла в файловой системе. Для работы с виртуальными именами файлов предусмотрены специальные команды. Команда ::safe::interpConfigure позволяет задавать новый виртуальный путь для интерпретатора. Команда ::safe::interpAddToAccessPath позволяет добавлять каталоги к виртуальному пути указанного безопасного интерпретатора. Команда ::safe::interpFindInAccessPath позволяет найти каталог в виртуальном пути для безопасного интерпретатора и получить его метку. Если каталог не найден, выдается сообщение об ошибке.

Команда ::safe::setLogCommand позволяет задать скрипт, который выполняется при каждом событии в безопасном интерпретаторе. Этот скрипт вызывается с одним аргументом - строкой, содержащей описание события.

## СИНОНИМЫ

При создании безопасного интерпретатора в нем определяются следующие команды - синонимы:

source fileName
  Аналогична команде source, однако позволяет работать только с файлами в виртуальном пути безопасного интерпретатора. Имя файла fileName должно содержать одну из меток, определенных для каталогов в виртуальном пути. Допустимые имена файлов более подробно описаны ниже (см. "Безопасность").
load fileName
  Требуемый файл (обычно, объектный файл из разделяемой библиотеки) загружается в безопасный интерпретатор, если его удается найти. Имя файла должно содержать одну из меток для каталогов виртуального пути. Кроме того, разделяемый объектный файл должен содержать безопасную точку входа. Подробности приведены в описании команды load.
file ?options?
  Синоним команды file содержит только безопасные подкоманды обычной команды file, а именно: dirname, join, extension, root, tail, pathname и split. Назначение подкоманд приведено в описании команды file.
exit
  При выполнении команды безопасный интерпретатор удаляется, вычисления в нем прерываются, но родительский интерпретатор продолжает существовать.

## КОМАНДЫ

В родительском интерпретаторе для работы с безопасными интерпретаторами предусмотрены следующие команды:

::safe::interpCreate ?slave? ?options...?
  Создает безопасный интерпретатор, инициализирует в нем команды - синонимы, описанные выше, и механизмы автозагрузки команд и пакетов в соответствии с заданными опциями (см. "Опции"). Если аргумент slave отсутствует, имя интерпретатора формируется автоматически. Команда всегда возвращает имя созданного интерпретатора.
::safe::interpInit slave ?options...?
  Команда аналогична предыдущей, однако интерпретатор должен быть уже создан каким-либо иным способом, например с помощью команды ::interp create-safe.
::safe::interpConfigure slave ?options...?
  Если опции не заданы, возвращает значения всех опций для указанного безопасного интерпретатора. В противном случае устанавливает указанные значения опций (подробнее см. "Опции").
::safe::interpDelete slave
  Удаляет безопасный интерпретатор и вычищает в родительском интерпретаторе информацию о нем. Перед удалением выполняется скрипт, заданный с помощью опции -deletehook, если он был задан. К скрипту добавляется дополнительный аргумент - имя удаляемого интерпретатора.
::safe::interpFindInAccessPath slave directory
  Команда возвращает метку, которую можно использовать в безопасном интерпретаторе для каталога directory. Если в виртуальном пути нет такого каталога, возвращается сообщение об ошибке. Пример использования команды:

      	  ###Создание безопасного интерпретатора
      	  ::safe::interpCreate qqq
      	  ###Присваивание переменной tk_library метки соответствующего каталога
      	  qqq eval [list set tk_library 	      [::safe::interpFindInAccessPath qqq ]]
      	  ###Выполнение команды source в безопасном интерпретаторе
      	  qqq eval source $tk_library/msgbox.tcl

::safe::interpAddToAccessPath slave directory
  Команда позволяет добавить к виртуальному пути указанного безопасного интерпретатора каталог directory. Команда возвращает значение метки для каталога directory. Если каталог уже содержался в виртуальном пути, команда только возвращает его метку и не добавляет его в виртуальный путь. Пример использования команды (см. пример к предыдущей команде):

      	  ::safe::interpAddToAccessPath qqq
      	  qqq eval source $my_lib/$my_file

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

  Эта команда позволяет задать скрипт, который будет выполняться при различных событиях, связанных с безопасными интерпретаторами. Если команда вызвана без аргументов, то она возвращает установленный ранее скрипт. Вызванная с одним аргументом - пустой строкой - команда удаляет установленный ранее скрипт и отменяет процесс журнализации. Установленный скрипт выполняется с одним дополнительным аргументом - строкой, описывающей событие. Основное назначение команды - использование при отладке скриптов, выполняемых в безопасных интерпретаторах. Используя ее, вы сможете получить полную информацию об ошибке, в то время как безопасный интерпретатор возвращает только обобщенное сообщение об ошибке (это позволяет избежать разглашения в сообщении об ошибке конфиденциальной информации, например, о реальных именах файлов). Пример использования:

      	  ::safe::setLogCmd puts stderr

  Ниже приведен журнал сессии, в которой безопасный интерпретатор пытается прочитать файл, который не найден в виртуальном пути. Обратите внимание, что сам безопасный интерпретатор получает при этом только сообщение о том, что файл не найден:

      	  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 {(:0:)}
      	  ERROR for slave interp10 : /foo/bar/init.tcl: no such file
      	  or directory

## ОПЦИИ

Для команд ::safe::interpCreate, ::safe::interpInit, и :safe::interpConfigure определены перечисленные ниже опции. Имена опций могут быть сокращены до минимальных однозначных имен. Имена опций не чувствительны к регистру, в котором они набраны.

-accessPath ?directoryList?
  Опция задает список каталогов, к которым может иметь доступ безопасный интерпретатор, и возвращает метки соответствующих каталогов. Если список не задан или если он пуст, безопасный интерпретатор получает доступ к каталогам, используемым для автозагрузки в родительском интерпретаторе. Подробнее см. "Безопасность".
-noStatics
  Если эта опция задана, то не допускается загрузка статически связанных пакетов (как load {} Tk). По умолчанию загрузка таких пакетов разрешена.
-nestedLoadOk
  Если эта опция задана, безопасный интерпретатор может загружать пакеты в собственные подинтерпретаторы. По умолчанию загрузка пакетов в подинтерпретаторы запрещена.
-deleteHook ?script?
  Если скрипт задан, он выполняется в родительском интерпретаторе (с дополнительным аргументом - именем безопасного интерпретатора) перед удалением безопасного интерпретатора. Если скрипт не задан, то удаляется заданный ранее скрипт (если такой был) и никаких дополнительных действий перед удалением безопасного интерпретатора не производится. По умолчанию скрипт не задан.

## БЕЗОПАСНОСТЬ

Save Tcl не дает полной гарантии безопасности. В частности, он не защищает от атак на сервер, когда поглощаются все ресурсы процессора и пользователь не может использовать компьютер для полезной работы. Однако такие атаки считаются, как правило, менее опасными, чем несанкционированный доступ к информации и нарушение целостности, от которых безопасный интерпретатор защищает. В безопасном интерпретаторе, помимо безопасного набора команд, который описан в описании команды interp, имеются синонимы для команд source, load, exit и безопасное подмножество подкоманд команды file. В безопасном интерпретаторе возможна автозагрузка библиотек и пакетов. Поскольку эти команды имеют дело с локальной файловой системой, существует потенциальная опасность использования их для доступа к конфиденциальной информации. Чтобы предотвратить эту возможность, в безопасном интерпретаторе используются не настоящие имена каталогов, а специальные метки. Эти метки транслируются в реальные имена файлов только в родительском интерпретаторе.

Чтобы исключить доступ к файлам, которые оказались в силу тех или иных причин в разрешенных для чтения в безопасном интерпретаторе каталогах, синоним команды source обеспечивает доступ только к файлам с расширением tcl, в именах которых содержится ровно одна точка, а общая длина имени не превышает четырнадцати символов.

По умолчанию в Tcl переменной auto_path содержатся метки для каталогов, содержащихся в аналогичной переменной в родительском интерпретаторе и их непосредственных подкаталогов. Первая метка в списке присваивается также Tcl переменной tcl_library безопасного интерпретатора. Вы можете сократить этот список, в явном виде задав доступные каталоги для безопасного интерпретатора с помощью опции -accessPath.

Safe Tcl - это механизм безопасного исполнения ненадежных Tcl скриптов и предоставления этим скриптам опосредованного доступа к потенциально опасным функциям.

Safe Tcl служит для того, чтобы ненадежные скрипты не смогли нарушить работу вызывающего их приложения: он предотвращает покушения на несанкционированный доступ к информации и нарушение целостности вызывающего этот скрипт процесса.

Safe Tcl позволяет интерпретатору-предку создавать безопасные интерпретаторы с ограниченными возможностями, в которых содержится набор предопределенных синонимов для команд source, load, file и exit и сохраняются возможности автозагрузки команд и пакетов.

Безопасный интерпретатор не позволяет получить какую-либо информацию о структуре файловой системы, поскольку для доступа к файлам в безопасном интерпретаторе используются специальные метки. Когда безопасный интерпретатор запрашивает доступ к файлу, он использует метку как часть виртуального имени файла. Родительский интерпретатор заменяет метку на реальное имя каталога и выполняет требуемую операцию с файлом. С помощью опций команд, описанных ниже, можно выбрать требуемый уровень безопасности интерпретатора.

Все команды для работы с безопасными интерпретаторами содержатся в пространстве имен safe. Команда ::safe::interpCreate создает безопасный интерпретатор. Возможные опции команды описаны ниже, см. "Опции".

Команда возвращает имя созданного интерпретатора. Команда ::safe::interpInit аналогична, но ее первым аргументом должно быть имя интерпретатора, созданного с помощью команды interp.

Команда ::safe::interpDelete удаляет интерпретатор, имя которого использовано в качестве аргумента. Команда ::safe::interpConfigure позволяет задать опции для безопасного интерпретатора или получить информацию об заданных ранее опциях. Подробно опции описаны ниже (см. Опции).

Для каждого безопасного интерпретатора, созданного с помощью команды ::safe::interpCreate или инициированного с помощью команды ::safe::interpInit в родительском интерпретаторе создается список доступных каталогов - виртуальный путь. Каждый каталог в пути связывается с реальным каталогом локальной файловой системы и с меткой, доступной в безопасном интерпретаторе. В результате надежный интерпретатор обходится без сведений о реальной файловой системе на машине, на которой исполняется интерпретатор. Когда в надежном интерпретаторе используется метка для доступа к конкретному файлу (например, для выполнения команды source или load), метка заменяется в родительском интерпретаторе на настоящее имя каталога и необходимый файл ищется в файловой системе. Надежный интерпретатор не получает сведений о реальном имени файла в файловой системе. Для работы с виртуальными именами файлов предусмотрены специальные команды. Команда ::safe::interpConfigure позволяет задавать новый виртуальный путь для интерпретатора. Команда ::safe::interpAddToAccessPath позволяет добавлять каталоги к виртуальному пути указанного безопасного интерпретатора. Команда ::safe::interpFindInAccessPath позволяет найти каталог в виртуальном пути для безопасного интерпретатора и получить его метку. Если каталог не найден, выдается сообщение об ошибке.

Команда ::safe::setLogCommand позволяет задать скрипт, который выполняется при каждом событии в безопасном интерпретаторе. Этот скрипт вызывается с одним аргументом - строкой, содержащей описание события.