<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>
<html>
  <head>
    <title>Safe Tcl</title>
  </head>

  <body>
    <h1>Safe Tcl</h1>

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

    <h2><a name=СИНТАКСИС></a>СИНТАКСИС</h2>

    <pre>
      <a href=#safe::interpCreate>::safe::interpCreate</a> ?<em>slave</em>? ?<em>options</em>...?
      <a href=#safe::interpInit>::safe::interpInit</a> <em>slave</em> ?<em>options</em>...?
      <a href=#safe::interpConfigure>::safe::interpConfigure</a> <em>slave</em> ?<em>options</em>...?
      <a href=#safe::interpDelete>::safe::interpDelete</a> <em>slave</em>
      <a href=#safe::interpAddToAccessPath>::safe::interpAddToAccessPath</a> <em>slave</em> <em>directory</em>
      <a href=#safe::interpFindInAccessPath>::safe::interpFindInAccessPath</a> <em>slave</em> <em>directory</em>
      <a href=#safe::setLogCmd>::safe::setLogCmd</a> ?<em>cmd</em> <em>arg</em>...?
    </pre>
      
    <h2><a name=ОПИСАНИЕ></a>ОПИСАНИЕ</h2>
    
    <p><strong>Safe Tcl</strong> - это механизм безопасного исполнения
      ненадежных Tcl скриптов и предоставления этим скриптам
      опосредованного доступа к потенциально опасным функциям.</p>

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

    <p><strong>Safe Tcl</strong> позволяет интерпретатору-предку
      создавать безопасные интерпретаторы с ограниченными
      возможностями, в которых содержится набор предопределенных
      синонимов для команд <a
      href=source.html><strong>source</strong></a>, <a
      href=load.html><strong>load</strong></a>, <a
      href=file.html><strong>file</strong></a> и <a
      href=exit.html><strong>exit</strong></a> и сохраняются
      возможности автозагрузки команд и пакетов.</p>

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

    <p>Все команды для работы с безопасными интерпретаторами
      содержатся в пространстве имен safe. Команда <a href=
      #safe::interpCreate><strong>::safe::interpCreate</strong></a>
      создает безопасный интерпретатор. Возможные опции команды
      описаны ниже, см. &quot;<a href=#ОПЦИИ>Опции</a>&quot;.</p>

    <p>Команда возвращает имя созданного интерпретатора. Команда <a
	href=#safe::interpInit><strong>::safe::interpInit</strong></a>
	аналогична, но ее первым аргументом должно быть имя
	интерпретатора, созданного с помощью команды <a href=
	interp.html><strong>interp</strong></a>. Команда <a href=
	#safe::interpDelete><strong>::safe::interpDelete</strong></a>
	удаляет интерпретатор, имя которого использовано в качестве
	аргумента.  Команда <a href=#safe::interpConfigure
	><strong>::safe::interpConfigure</strong></a> позволяет задать
	опции для безопасного интерпретатора или получить информацию
	об заданных ранее опциях. Подробно опции описаны ниже
	(см. &quot;<a href=#ОПЦИИ>Опции</a>&quot;).</p>
    
    <p>Для каждого безопасного интерпретатора, созданного с помощью
      команды <a
      href=#safe::interpCreate><strong>::safe::interpCreate</strong></a>
      или инициированного с помощью команды <a
      href=#safe::interpInit><strong>::safe::interpInit</strong></a>
      в родительском интерпретаторе создается список доступных
      каталогов - виртуальный путь. Каждый каталог в пути связывается
      с реальным каталогом локальной файловой системы и с меткой,
      доступной в безопасном интерпретаторе. В результате надежный
      интерпретатор обходится без сведений о реальной файловой системе
      на машине, на которой исполняется интерпретатор. Когда в
      надежном интерпретаторе используется метка для доступа к
      конкретному файлу (например, для выполнения команды <a
      href=source.html><strong>source</strong></a> или <a
      href=load.html><strong>load</strong></a>), метка заменяется в
      родительском интерпретаторе на настоящее имя каталога и
      необходимый файл ищется в файловой системе. Надежный
      интерпретатор не получает сведений о реальном имени файла в
      файловой системе. Для работы с виртуальными именами файлов
      предусмотрены специальные команды. Команда <a href=
      #safe::interpConfigure><strong>::safe::interpConfigure</strong></a>
      позволяет задавать новый виртуальный путь для интерпретатора.
      Команда <a href=#safe::interpAddToAccessPath
      ><strong>::safe::interpAddToAccessPath</strong></a> позволяет
      добавлять каталоги к виртуальному пути указанного безопасного
      интерпретатора. Команда <a href=#safe::interpFindInAccessPath
      ><strong>::safe::interpFindInAccessPath</strong></a> позволяет
      найти каталог в виртуальном пути для безопасного интерпретатора
      и получить его метку. Если каталог не найден, выдается сообщение
      об ошибке.</p>

    <p>Команда <a href=#safe::setLogCmd
      ><strong>::safe::setLogCommand</strong></a> позволяет задать
      скрипт, который выполняется при каждом событии в безопасном
      интерпретаторе.  Этот скрипт вызывается с одним аргументом -
      строкой, содержащей описание события.</p>

    <h2><a name=СИНОНИМЫ></a>СИНОНИМЫ</h2>

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

    <dl>
      <dt><strong>source</strong> <em>fileName</em></dt>

      <dd>Аналогична команде <a
	href=source.html><strong>source</strong></a>, однако
	позволяет работать только с файлами в виртуальном пути
	безопасного интерпретатора. Имя файла <em>fileName</em> должно
	содержать одну из меток, определенных для каталогов в
	виртуальном пути. Допустимые имена файлов более подробно
	описаны ниже (см. &quot;<a
	href=#БЕЗОПАСНОСТЬ>Безопасность</a>&quot;).
      </dd>

      <dt><strong>load</strong> <em>fileName</em></dt>
      
      <dd>Требуемый файл (обычно, объектный файл из разделяемой
	библиотеки) загружается в безопасный интерпретатор, если его
	удается найти. Имя файла должно содержать одну из меток для
	каталогов виртуального пути. Кроме того, разделяемый объектный
	файл должен содержать безопасную точку входа.  Подробности
	приведены в описании команды
	<a href=load.html><strong>load</strong></a>.
      </dd>

      <dt><strong>file</strong> ?<em>options</em>?</dt>

      <dd>Синоним команды <a href=file.html><strong>file</strong></a> содержит
	только безопасные подкоманды обычной команды <a href=
	file.html><strong>file</strong></a>, а именно: <a
	href=file.html#dirname><strong>dirname</strong></a>,
	<a href=file.html#join><strong>join</strong></a>,
	<a href=file.html#extension><strong>extension</strong></a>,
	<a href=file.html#rootname><strong>root</strong></a>,
	<a href=file.html#tail><strong>tail</strong></a>,
	<a href=file.html#pathname><strong>pathname</strong></a> и
	<a href=file.html#split><strong>split</strong></a>.
	Назначение подкоманд приведено в
	описании команды <a href=file.html><strong>file</strong></a>.
      </dd>

      <dt><strong>exit</strong></dt>

      <dd>При выполнении команды безопасный
	интерпретатор удаляется, вычисления в нем прерываются, но
	родительский интерпретатор продолжает существовать.
      </dd>
    </dl>

    <h2><a name=КОМАНДЫ></a>КОМАНДЫ</h2>

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

    <dl>
      <dt><a name=safe::interpCreate></a><strong>::safe::interpCreate</strong>
	?<em>slave</em>?  ?<em>options</em>...?</dt>
      
      <dd>Создает безопасный интерпретатор, инициализирует в нем
	команды - синонимы, описанные выше, и механизмы автозагрузки
	команд и пакетов в соответствии с заданными опциями
	(см. &quot;<a href=#ОПЦИИ>Опции</a>&quot;). Если аргумент
	slave отсутствует, имя интерпретатора формируется
	автоматически.  Команда всегда возвращает имя созданного
	интерпретатора.
      </dd>
      
      <dt><a name=safe::interpInit></a><strong>::safe::interpInit</strong>
	<em>slave</em> ?<em>options</em>...?</dt>

      <dd>Команда аналогична предыдущей, однако интерпретатор должен
	быть уже создан каким-либо иным способом, например с помощью
	команды <strong>::interp create-safe</strong>.
      </dd>

      <dt><a
	name=safe::interpConfigure></a><strong>::safe::interpConfigure</strong>
	<em>slave</em> ?<em>options</em>...?</dt>

      <dd>Если опции не заданы, возвращает значения всех опций для
	указанного безопасного интерпретатора. В противном случае
	устанавливает указанные значения опций (подробнее см. &quot;<a
	href=#ОПЦИИ>Опции</a>&quot;).
      </dd>

      <dt><a name=safe::interpDelete>
	</a><strong>::safe::interpDelete</strong> <em>slave</em></dt>

      <dd>Удаляет безопасный интерпретатор и
	вычищает в родительском интерпретаторе информацию о нем. Перед
	удалением выполняется скрипт, заданный с помощью опции <strong>
	-deletehook</strong>, если он был задан. К скрипту добавляется
	дополнительный аргумент - имя удаляемого интерпретатора.
      </dd>

      <dt><a name=safe::interpFindInAccessPath>
	</a><strong>::safe::interpFindInAccessPath</strong> <em>slave</em>
	<em>directory</em></dt>

      <dd> Команда возвращает метку, которую можно использовать в
        безопасном интерпретаторе для каталога <em>directory</em>.  Если
        в виртуальном пути нет такого каталога, возвращается сообщение
        об ошибке. Пример использования команды:
	<pre>
	  ###Создание безопасного интерпретатора 
	  ::safe::interpCreate qqq
	  ###Присваивание переменной tk_library метки соответствующего каталога
	  qqq eval [list set tk_library 	      [::safe::interpFindInAccessPath qqq ]] 
	  ###Выполнение команды source в безопасном интерпретаторе
	  qqq eval source $tk_library/msgbox.tcl
	</pre>
      </dd>

      <dt><a name=safe::interpAddToAccessPath>
	</a><strong>::safe::interpAddToAccessPath</strong> <em>slave</em>
	<em>directory</em></dt>

      <dd> Команда позволяет добавить к виртуальному пути указанного
        безопасного интерпретатора каталог <em>directory</em>.  Команда
        возвращает значение метки для каталога <em> directory</em>. Если
        каталог уже содержался в виртуальном пути, команда только
        возвращает его метку и не добавляет его в виртуальный
        путь. Пример использования команды (см.  пример к предыдущей
        команде):
	<pre>
	  ::safe::interpAddToAccessPath qqq  
	  qqq eval source $my_lib/$my_file
	</pre>
      </dd>

      <dt><a name=safe::setLogCmd>
	</a><strong>::safe::setLogCmd</strong> ?<em>cmd</em> <em>arg</em>...?</dt>
      
      <dd><p>Эта команда позволяет задать скрипт, который будет
	  выполняться при различных событиях, связанных с безопасными
	  интерпретаторами. Если команда вызвана без аргументов, то
	  она возвращает установленный ранее скрипт. Вызванная с одним
	  аргументом - пустой строкой - команда удаляет установленный
	  ранее скрипт и отменяет процесс журнализации.  Установленный
	  скрипт выполняется с одним дополнительным аргументом -
	  строкой, описывающей событие. Основное назначение команды -
	  использование при отладке скриптов, выполняемых в безопасных
	  интерпретаторах. Используя ее, вы сможете получить полную
	  информацию об ошибке, в то время как безопасный
	  интерпретатор возвращает только обобщенное сообщение об
	  ошибке (это позволяет избежать разглашения в сообщении об
	  ошибке конфиденциальной информации, например, о реальных
	  именах файлов). Пример использования:</p>
	<pre>
	  ::safe::setLogCmd puts stderr
	</pre>
        <p>Ниже приведен журнал сессии, в которой безопасный
	  интерпретатор пытается прочитать файл, который не найден в
	  виртуальном пути. Обратите внимание, что сам безопасный
	  интерпретатор получает при этом только сообщение о том, что
	  файл не найден:</p>
	<pre>
	  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
	</pre>
      </dd>
    </dl>

    <h2><a name=ОПЦИИ></a>ОПЦИИ</h2>
    
    <p>Для команд <strong>::safe::interpCreate</strong>,
      <strong>::safe::interpInit</strong>, и <strong>:safe::interpConfigure</strong>
      определены перечисленные ниже опции. Имена опций могут быть
      сокращены до минимальных однозначных имен. Имена опций не
      чувствительны к регистру, в котором они набраны.</p>

    <dl>
      <dt><strong>-accessPath</strong> ?<em>directoryList</em>?</dt>

      <dd>Опция задает список каталогов, к которым может иметь доступ
	безопасный интерпретатор, и возвращает метки соответствующих
	каталогов. Если список не задан или если он пуст, безопасный
	интерпретатор получает доступ к каталогам, используемым для
	автозагрузки в родительском интерпретаторе.  Подробнее
	см. &quot;<a href=#БЕЗОПАСНОСТЬ>Безопасность</a>&quot;.</dd>

      <dt><strong>-noStatics</strong></dt>

      <dd>Если эта опция задана, то не допускается загрузка статически
	связанных пакетов (как <strong>load {} Tk</strong>). По умолчанию
	загрузка таких пакетов разрешена.
      </dd>

      <dt><strong>-nestedLoadOk</strong></dt>

      <dd>Если эта опция задана, безопасный интерпретатор может
	загружать пакеты в собственные подинтерпретаторы. По умолчанию
	загрузка пакетов в подинтерпретаторы запрещена.
      </dd>

      <dt><strong>-deleteHook</strong> ?<em>script</em>?</dt>

      <dd>Если скрипт задан, он выполняется в родительском
	интерпретаторе (с дополнительным аргументом - именем
	безопасного интерпретатора) перед удалением безопасного
	интерпретатора. Если скрипт не задан, то удаляется заданный
	ранее скрипт (если такой был) и никаких дополнительных
	действий перед удалением безопасного интерпретатора не
	производится. По умолчанию скрипт не задан.</dd>
    </dl>

    <h2><a name=БЕЗОПАСНОСТЬ></a>БЕЗОПАСНОСТЬ</h2>

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

    <p>Чтобы исключить доступ к файлам, которые оказались в силу тех
      или иных причин в разрешенных для чтения в безопасном
      интерпретаторе каталогах, синоним команды <a
      href=source.html><strong>source</strong></a> обеспечивает
      доступ только к файлам с расширением tcl, в именах которых
      содержится ровно одна точка, а общая длина имени не превышает
      четырнадцати символов.</p>

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

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

    <p><strong>Safe Tcl</strong> позволяет интерпретатору-предку создавать
      безопасные интерпретаторы с ограниченными возможностями, в
      которых содержится набор предопределенных синонимов для команд
      <a href=source.html><strong>source</strong></a>, <a
      href=load.html><strong>load</strong></a>, <a
      href=file.html><strong>file</strong></a> и <a
      href=exit.html><strong>exit</strong></a> и сохраняются возможности
      автозагрузки команд и пакетов.</p>

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

    <p>Все команды для работы с безопасными интерпретаторами
      содержатся в пространстве имен safe. Команда
      <strong>::safe::interpCreate</strong> создает безопасный интерпретатор.
      Возможные опции команды описаны ниже, см. <a
      href=#ОПЦИИ>&quot;Опции&quot;</a>.</p>

    <p>Команда возвращает имя созданного интерпретатора. Команда
      <strong>::safe::interpInit</strong> аналогична, но ее первым аргументом
      должно быть имя интерпретатора, созданного с помощью команды
      <strong><a href=interp.html>interp</a></strong>.</p>

    <p>Команда <strong>::safe::interpDelete</strong> удаляет интерпретатор, имя
      которого использовано в качестве аргумента. Команда
      <strong>::safe::interpConfigure</strong> позволяет задать опции для
      безопасного интерпретатора или получить информацию об заданных
      ранее опциях. Подробно опции описаны ниже (см. <a
      href=#ОПЦИИ>Опции</a>).</p>

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

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