RFC: 3920
Оригинал: Extensible Messaging and Presence Protocol (XMPP): Core
Другие версии: RFC 6120
Категория: Предложенный стандарт
Дата публикации:
Автор:
Перевод: Семенов Юрий Алексеевич

Статус документа

Это документ содержит проект стандарта протокола Internet для Internet-сообщества и служит приглашением к дискуссии в целях развития и совершенствования протокола. Текущее состояние стандартизации и статус протокола можно узнать из текущей версии документа "Internet Official Protocol Standards" (STD 1). Допускается свободное распространение документа.

Тезисы

Этот документ определяет основные особенности протокола XMPP (eXtensible Messaging and Presence Protocol — расширяемый протокол обмена сообщениями и данными о присутствии), протокола, использующего XML (eXtensible Markup Language — расширяемый язык разметки) для обмена структурированной информацией в режиме близком к реальному времени между двумя любыми сетевыми оконечными точками.

Оглавление

1. Введение

Расширяемый протокол обмена сообщениями и данными о присутствии XMPP (Extensible Messaging and Presence Protocol) является открытым протоколом, использующими XML (Extensible Markup Language [XML]) для сервисов обмена сообщениями в режиме близком к реальному времени, данными о присутствии, запросами/откликами. Базовый синтаксис и семантика были разработаны первоначально в 1999 году сообществом разработчиков системы Jabber с общедоступным кодом. В 2002 рабочая группа XMPP занялась адаптацией протокола Jabber, который должен стать основой технологии обмена сообщениями в реальном масштабе времени (IM) и данными о присутствии сообщества IETF. Результатом работы группы XMPP стал данный документ, который определяет базовые черты XMPP 1.0; расширения, необходимые для реализации обмена сообщениями и данными о присутствии в реальном масштабе времени, определены в RFC-2779 [IMP-REQS] и специфицированы в протоколе XMPP: передача сообщений и данных о присутствии в реальном масштабе времени [XMPP-IM].

2. Обобщенная архитектура

Хотя XMPP не привязан к какой-то определенной сетевой архитектуре, реализация сессии осуществляется по схеме клиент-сервер, где клиент реализует подключение к серверу с помощью [TCP] TCP-транспорта, и сами серверы взаимодействуют друг с другом также, используя протокол ТСР.

На рисунке ниже представлена схема высокоуровневой архитектуры подобной сессии ("-" коммуникации, использующие XMPP протокол, "=" — коммуникации, использующие какой-либо другой протокол).

C1----S1---S2---C3
      |
C2----+--G1===FN1===FC1

Символы на рисунке имеют следующие значения:

  • C1, C2, C3 = XMPP клиенты
  • S1, S2 = XMPP серверы
  • G1 = шлюз, который осуществляет согласования XMPP и протоколов, используемых в сети без поддержки XMPP.
  • FN1 = внешняя сеть без поддержки XMPP
  • FC1 = клиент сети без поддержки XMPP

2.2. Сервер

Сервер действует как интеллектуальный уровень абстракции для XMPP коммуникаций. Его основные обязанности:

  • установление и поддержание соединения или сессии с другими объектами, в виде XML-потоков (раздел 4) к или от авторизованных клиентов, серверов и прочих объектов.

  • маршрутизацию корректно адресованных строф (stanzas) (раздел 9) между такими объектами в рамках XML-потоков.

Большинство XMPP-совместимых серверов осуществляют также запоминание данных, которые используются клиентами (например, список контактов для пользователей системы обмена сообщениями и данными о присутствии с помощью XMPP); в этом случае, XML-данные обрабатываются непосредственно сервером для клиента, а не переадресуются другому объекту.

2.3. Клиент

Большинство клиентов подключается непосредственно к серверу посредством TCP и используют XMPP для получения полной функциональности, доступной на сервере. Для каждого авторизованного клиента к серверу могут одновременно подключаться несколько ресурсов (например, устройств или позиций). Каждый ресурс характеризуется идентификатором XMPP-адреса (например, <[email protected] /home> или <[email protected] /work>), как это определено схемой адресации (раздел 3). Рекомендованным номером порта для соединения клиента с сервером является 5222, как это фиксировано IANA (смотри "Номера портов" (раздел 15)).

2.4. Шлюз

Шлюз является специальной функцией сервера, задача которой заключается в трансляции протокола XMPP для внешних систем обмена сообщениями, которые не поддерживают XMPP, а также преобразовании данных, поступающих из удаленных сетей, не поддерживающих XMPP. Примерами могут служить шлюзы для электронной почты (смотри [SMTP]), IRC (Internet Relay Chat, смотри [IRC]), SIMPLE (смотри [SIMPLE]), SMS (Short Message Service), а также сервисы типа AIM, ICQ, MSN Messenger или Yahoo! Instant Messenger.

2.5. Сеть

Так как каждый сервер идентифицируется сетевым адресом и так как коммуникации сервер-сервер являются простым расширение протокола клиент-сервер, на практике система представляет собой сеть серверов, которые взаимодействуют друг с другом. Таким образом, например, <[email protected] > может обмениваться сообщениями и данными о присутствии, а также другой информацией с <[email protected] >. Эта схема подобна протоколам обмена сообщениями (таким как [SMTP]), которые используют стандарты сетевой адресации. Коммуникации между любыми двумя серверами являются опционными. Если они разрешены, такие коммуникации должны осуществляться посредством XML-потоков, которые сопряжены с TCP-соединениями. Рекомендуемым номером порта для соединения серверов является 5269 (смотри главу "Номера портов" (раздел 15)).

3. Схема адресации

3.1. Overview

Объектом считается нечто, что может рассматриваться, как конечная точка сети (т.е., ID для сети) и что может осуществлять обмен с использованием XMPP. Все такие объекты являются уникально адресуемыми в формате, совместимом с RFC 2396 [URI]. По историческим причинам адрес XMPP-объекта называется идентификатором Jabber или JID. JID содержит набор элементов, образующих доменный идентификатор, идентификатор узла или ресурса.

Синтаксис JID описан ниже в формализме Бакуса-Наура, определенном в [ABNF].

jid             = [ node "@" ] domain [ "/" resource ]
domain          = fqdn / address-literal
fqdn            = (sub-domain 1*("." sub-domain))
sub-domain      = (internationalized domain label)
address-literal = IPv4address / IPv6address

Все JID базируются на следующей структуре. Наиболее общим использованием этой структуры является идентификация пользователя системы обмена сообщениями, сервера, к которому пользователь подключается и используемых ресурсов в форме <[email protected] /resource>. однако, возможны типы узлов, отличные от клиентов; например, специальная комната для разговоров, предлагаемая многопользовательским сервисом, может адресоваться как <[email protected] > (где "room" является именем chat room, а "service" имя машины, предлагающей этот вид сервиса. Определенный участник такой беседы может адресоваться как <[email protected] /nick> (где "nick" — имя/прозвище участника такой сессии). Возможно много других типов JID (например, <domain/resource> может быть скриптом или сервисом на стороне сервера).

Каждая из возможных частей JID (идентификаторы узла, домена и ресурса) не должны содержать более 1023 байт, что устанавливает максимальный размер, включая символы '@' и '/', равный 3071 байту.

3.2. Идентификатор домена

Идентификатор домена является первичным идентификатором и представляет собой единственный обязательный элемент JID (простой идентификатор домена является корректным значением JID). Он обычно представляет сетевой шлюз или "первичный" сервер, к которому подключаются другие объекты для осуществления XML-маршрутизации и управления данными. Однако объект, адресуемый идентификатором домена, не обязательно является сервером и может быть сервисом, который адресуется как субдомен сервера, который обеспечивает функциональность, неподдерживаемую сервером (например, пользовательский каталог или шлюз к удаленной системе обмена сообщениями).

Идентификатором домена для каждого сервера или сервиса, который будет обмениваться данными через сеть, может быть IP-адрес, но он должен обязательно соответствовать имени домена [DNS]. Идентификатор домена должен иметь международное доменное имя, как это определено в [IDNA]. Прежде чем сравнивать два идентификатора доменов сервер должен (также как и клиент) использовать профайл Nameprep для меток (как это задано в [IDNA]).

3.3. Идентификатор узла

Идентификатор узла является опционным вторичным идентификатором, размещаемым перед доменным идентификатором, и отделяемым от него символом '@'. Он обычно представляет собой объект, запрашивающий и использующий доступ к сети, предоставляемый сервером или шлюзом (т.е., клиент). Хотя он может представлять собой и другой объект. Объект, представляемый идентификатором узла адресуется в рамках контекста конкретного домена; для задач обмена сообщениями и данными о присутствии приложений XMPP, этот адрес называется "чистым JID" и имеет вид <[email protected] >.

Идентификатор узла должен быть сформатирован так, чтобы можно было использовать профайл Nodeprep [STRINGPREP]. Прежде чем сравнивать два идентификатора узлов, сервер должен сначала использовать профайл Nodeprep для каждого идентификатора.

3.4. Идентификатор ресурса

Идентификатор ресурса является опционным третичным идентификатором, размещаемым после идентификатора домена и отделенным от последнего символом '/'. Идентификатор ресурса может варьироваться от <[email protected] > до <domain>. Он обычно представляет определенную сессию, соединение, например, устройство или положение), или объект (например, участник многопользовательского обмена сообщениями), принадлежащее сущности, ассоциированной с идентификатором узла. Идентификатор ресурса не прозрачен для сервера и других клиентов, и обычно определяется реализацией клиента, когда он выдает информацию, нужную для завершения подключения ресурса (Resource Binding, раздел 7). Объект может содержать несколько подключенных ресурсов. Каждый подключенный ресурс имеет свой идентификатор.

Идентификатор ресурса должен быть сформирован так, чтобы было можно применить профайл Resourceprep [STRINGPREP]. Прежде чем сравнивать два идентификатора ресурсов, сервер должен сначала использовать профайл Resourceprep для каждого идентификатора.

3.5. Определение адреса

После согласования SASL (раздел 6) и, если нужно, подключения ресурсов (раздел 7), принимающий объект должен определить начальное значение JID.

Для обменов сервер-сервер, начальное значение JID должно определять авторизационную идентичность, как это определено спецификацией уровня безопасности и простой аутентификации SASL (Simple Authentication and Security Layer) [SASL] (раздел 6).

Для коммуникаций клиент-клиент "чистый JID" (<[email protected] >) должен определять авторизационную идентичность, как это определено спецификацией [SASL], (раздел 6). Секция идентификатора ресурса "чистого JID" (<[email protected] /resource>) должна быть ресурсным идентификатором, согласованным клиентом и сервером при подключении ресурса (раздел 7).

Принимающий объект должен гарантировать, что результирующий JID (включая идентификатор узла, домена, ресурса и разделительные символы) соответствует правилам и форматам, определенным ранее в данном разделе; чтобы удовлетворить этим ограничениям, принимающий объект может быть вынужден заменить JID, присланный инициатором обмена.

4. XML потоки

4.1. Overview

Два фундаментальных принципа делают возможным быстрый асинхронный обмен при сравнительно небольшом поле данных: XML-потоки и XML-строфы (stanzas). Эти термины определяются следующим образом:

  • Определение XML-потока:
  • XML-поток является контейнером для обмена XML-элементами между объектами через сеть. Начало XML-потока однозначно определяется открывающим XML-тэгом <stream> (с декларацией соответствующих атрибутов названий позиций), в то время как конец XML-потока однозначно определяется закрывающим XML-тэгом </stream>. Во время существования потока, объект его инициировавший, может посылать произвольное число XML-элементов, либо элементов, используемых для согласования параметров потока (например, для согласования использования TLS (раздел 5), либо использования SASL (раздел 6)), либо XML-строф (как это определяется, <message/>, <presence/> или <iq/>). "Исходный поток" согласуется инициатором сессии (обычно клиентом или сервером) с принимающим объектом (обычно сервером). Исходный поток обеспечивает однонаправленную коммуникацию между инициатором и получателем; для того чтобы разрешить информационный обмен от принимающей стороны к инициатору, приемник должен согласовать поток в обратном направлении ("поток-отклик").
  • Определение XML строфы:
  • XML-строфа является дискретным семантическим блоком структурированной информации, который посылается одним объектом другому объекту через XML-поток. XML-строфа является дочерним элементом по отношению элементу <stream/>. Начало любой XML-строфа однозначно определяется стартовым тэгом XML-потока (depth=1) (например, <presence>), а конец любой XML-строфы однозначно задается закрывающим тэгом (например, </presence>). XML-строфа может содержать дочерние элементы (сопроводительные атрибуты и XML-символы). Единственными видами XML-строф, определенными здесь, являются: <message/>>, <presence/> и <iq/> (раздел 9). XML-элементы, посланные для целей согласования транспортной безопасности TLS (Transport Layer Security) (раздел 5) и согласования SASL (раздел 6) не рассматриваются как XML-строфы.

Рассмотрим пример клиентской сесии взаимодействия с сервером. Для того чтобы соединиться с сервером, клиент должен инициировать XML-поток путем посылки серверу открывающего тэга <stream>, опционно перед ним может следовать текстовая декларация, специфицирующая XML-версию и символьное кодирование (смотри "Включение текстовых деклараций" (раздел 11); а также Кодирование символов (раздел 11)). В соответствии с локальной политикой и предоставляемыми сервисами сервер должен откликнуться и сформировать XML-поток к клиенту. Как только клиент завершает согласование SASL (раздел 6), он может посылать любое число XML-строф любому получателю в сети. Когда клиент захочет прервать сессию, он просто посылает серверу закрывающий тэг </stream> (поток может быть прерван также и сервером), после этого как клиент так и сервер разрывают ТСР-соединение.

По существу, XML-поток функционирует как конверт для всех XML-строф, посланных во время сессии. Мы можем представит это в упрощенной форме как:

|--------------------|
| <stream>           |
|--------------------|
| <presence>         |
|   <show/>          |
| </presence>        |
|--------------------|
| <message to='foo'> |
|   <body/>          |
| </message>         |
|--------------------|
| <iq to='bar'>      |
|   <query/>         |
| </iq>              |
|--------------------|
| ...                |
|--------------------|
| </stream>          |
|--------------------|

4.2. Связь с TCP

Хотя нет необходимости связывать XML-поток с ТСР-соединением [TCP] (например, два объекта могут установить соединение друг с другом посредством другого механизма, данная спецификация предполагает работу только с TCP-протоколом. В контексте коммуникаций клиент-сервер, сервер должен позволить клиенту разделять одно TCP-соединение для XML-строф, посланных клиентом серверу и от сервера клиенту. В контексте коммуникаций сервер-сервер, сервер должен использовать одно TCP-соединение для XML-строф, посланных сервером своему партнеру, и другое TCP-соединение (инициированное партнером) для передачи строф от партнера серверу.

4.3. Безопасность потока

Когда согласуется формирование XML-потоков в XMPP 1.0, следует использовать TLS, как это определено в разделе 5, а SASL должен использоваться при условиях, описанных в разделе 6. Безопасности исходного потока (т.е., потока от инициатора получателю) и поток-отклик (т.е., поток от получателя к инициатору) должны обеспечиваться независимо. Объект не должен пытаться посылать XML-строфы (раздел 9) через поток, прежде чем он будет аутентифицирован, но если он это сделает, тогда другой объект не должен воспринимать такие строфы и должен возвращать уведомление об ошибке <not-authorized/> и затем прерывать XML-поток и TCP-соединение; заметим, что здесь вовлечены только XML-строфы (т.е., элементы '<message/>, <presence/> и <iq/>), а не XML элементы, используемые для согласования параметров потока (например, элементы, используемые для согласования работы с TLS (раздел 5) или с SASL (раздел 6)).

4.4. Атрибуты потока

Существуют следующие атрибуты элемента потока:

  • to
  • Следует использовать только в заголовке XML-потока между инициатором и получателем. Значение этого атрибута должно соответствовать имени машины получателя. Не следует использовать атрибут 'to' в заголовках XML-потоков, где получатель посылает отклик инициатору; однако, если атрибут 'to' использован в таком контексте, он должен быть молча проигнорирован инициатором.
  • from
  • Следует использовать только в заголовках XML-потоков от получателя к инициатору, и его значение должно быть равно имени машины, обслуживаемой получателем. Не должно быть атрибутов 'from' в заголовках XML-потоков между инициатором и получателем; однако, если атрибут 'from' все же вставлен, он должен молча игнорироваться получателем.
  • id
  • Следует использовать только в заголовках XML-потоков от получателя к инициатору. Этот атрибут является уникальным идентификатором, сформированным получателем, для использования в качестве ключа сессии для потоков инициатора, и должен быть уникальным для принимающих приложений (в норме для сервера). Заметим, что ID-потока может быть критичным в отношении безопасности и, следовательно, непредсказуемым (рекомендации смотри в [RANDOM]). Не следует использовать атрибут 'id' в заголовках XML-потоков, посылаемых инициатором получателю; однако, если атрибут 'id' все же включен, он должен молча игнорироваться получателем.
  • xml:lang
  • Следует включать инициатором в заголовок, чтобы специфицировать язык по умолчанию для любых посылаемых им символьных данных. Если атрибут включен, получатель должен запомнить его в качестве значения по умолчанию как для исходного потока, так и для потока-отклика; если атрибут не был включен, получатель должен использовать для обоих потоков значение из конфигурации, которое он должен пересылать в заголовке потока-отклика. Для всех строф, переданных в исходном потоке, если инициатор не использовал атрибут 'xml:lang', получатель должен использовать значение по умолчанию; если инициатор включил атрибут 'xml:lang', получатель не должен модифицировать или удалять его (смотри также xml:lang (раздел 9)). Значение атрибута 'xml:lang' должно быть NMTOKEN (как это определено в разделе 2.3 of [XML]) и должно следовать формату, определенному в RFC 3066 [LANGTAGS].
  • version
  • Присутствие атрибута версии с значением, равным по крайней мере "1.0" сигнализирует о поддержке потоковых протоколов, описанных в данной спецификации.

Мы можем резюмировать следующее:

инициатор-получатель получатель-инициатор
to Имя машины получателя молча игнорируется
from молча игнорируется Имя машины получателя
id молча игнорируется ключ сессии
xml:lang язык по умолчанию язык по умолчанию
version Сигнал поддержки XMPP 1.0 Сигнал поддержки XMPP 1.0

4.4.1. Поддержка версии

Версия XMPP, специфицированная здесь, равна "1.0"; в частности, подразумевает протоколы, ориентированные на потоки, (использование TLS — раздел 5, использование SASL — раздел 6 и ошибки в потоках — раздел 4), а также семантику трех определенных типов XML-строф (<message/>, <presence/> и <iq/>). Схема нумерации версий XMPP имеет формат "<major>.<minor>". Старший и младший коды версии должны рассматриваться как отдельные целые числа и каждое число может инкрементироваться. Таким образом, "XMPP 2.4" будет более ранней версией чем "XMPP 2.13", которая в свою очередь младше, чем версия "XMPP 12.3". Лидирующие нули (например, "XMPP 6.01") должны игнорироваться получателями и не должны пересылаться.

Старший код номера версии следует инкрементировать только, если форматы потока или строф, или необходимые действия изменились настолько сильно, что объект старой версии не сможет их интерпретировать корректно. Младший код номера версии индицирует новые возможности, и он должен игнорироваться объектом более ранней версии. Например, младший код номера версии может указывать на возможность обработки вновь определенных типов атрибута сообщения, данных о присутствии, или IQ-строф. Объект с большим значением младшего кода версии будет знать, что его партнер не способен правильно воспринять новый тип атрибута, и не будет его посылать.

Следующие правила следует использовать при генерации и обработке атрибута 'version' в заголовках потоков:

  1. Инициатор должен установить значение атрибута 'version' в заголовке исходного потока равным наивысшей поддерживаемой версии (например, если наивысшая поддерживаемая им версия равна описанной в данном документе, он должен установить ее равной "1.0").

  2. Приемник должен установить значение атрибута 'version' в заголовке потока-отклика равным либо значению версии, присланной инициатором, либо наивысшему поддерживаемому значению приемника, в зависимости от того какое значение ниже. Приемник должен осуществлять числовое сравнение старшего и младшего кодов версии, а не использовать значение строки "<major>.<minor>".

  3. Если номер версии, включенный в заголовок потока-отклика является по крайней мере в старшей части меньше, чем код версии, включенный в заголовок исходного потока, сущности новой версии не смогут работать. Инициатор должен сформировать уведомление об ошибки <unsupported-version/> и прервать XML-поток и разорвать TCP-соединение.

  4. Если какой-либо объект получает заголовок без атрибута 'version', объект должен считать поддерживаемую версию объекта равной "0.0" и не должен включать атрибут 'version' в заголовок потока, который он посылает в виде отклика.

4.5. Декларации пространства имен

Потоковый элемент должен содержать декларации потокового пространства имен и пространства имен по умолчанию ("декларация пространства имен" определено XML спецификации пространства имен [XML-NAMES]).

4.6. Характеристики потока

Если инициатор включает атрибут 'version' в заголовок исходного потока со значением по крайней мере "1.0", приемник должен послать дочерний элемент <features/> (перед ним размещается префикс пространства имен потока) инициатору, для того чтобы анонсировать любые характеристики поточного уровня, которые могут быть согласованы (или возможности, которые нужно анонсировать). Сейчас, это используется только для анонсирования использования TLS (раздел 5), использования SASL (раздел 6) и подключаемых ресурсов (раздел 7), а также для установления сессий, как это определено в [XMPP-IM]; однако, функциональность потоковых характеристик может использоваться для анонсирования других согласуемых параметров в будущем. Если объект не понимает или не поддерживает некоторые возможности, он должен их молча игнорировать.

4.7. Ошибки потока

Корневой потоковый элемент может содержать дочерний элемент <error/>, перед которым следует префикс пространства имен потока. Дочерний элемент ошибки должен быть послан соответствующим объектом (обычно сервером, а не клиентом), если он понимает, что на поточном уровне произошла ошибка.

4.7.1. Правила

Следующие правила используются в отношении ошибок уровня потока:

  • Предполагается, что все ошибки потокового уровня являются неисправимыми; следовательно, если ошибка случается на уровне потока, объект, который детектирует ошибку должен послать сигнал потоковой ошибки другому объекту, послать закрывающий тэг </stream>, и завершить TCP-соединение.

  • Ошибка происходит, когда поток сформирован, получатель должен послать открывающий тэг <stream>, включить элемент <error/> в качестве дочернего, послать закрывающий тэг </stream> и разорвать TCP-соединение. В этом случае, если инициатор предлагает неизвестную машину в атрибуте 'to' (или вообще не предлагает атрибута 'to'), сервер должен выдать перед терминацией заслуживающее доверия имя машины в атрибуте 'from' заголовка потока.

4.7.2. Синтаксис

Синтаксис потоковых ошибок имеет следующий формат:

<stream:error>
  <defined-condition xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
  <text xmlns='urn:ietf:params:xml:ns:xmpp-streams'
        xml:lang='langcode'>
    OPTIONAL descriptive text
  </text>
  [OPTIONAL application-specific condition element]
</stream:error>

Элемент <error/>:

  • должен содержать дочерний элемент, соответствующий одной из выявленных ошибок строф; этот элемент должен быть задан пространством имен 'urn:ietf:params:xml:ns:xmpp-streams'

  • содержать дочерний элемент <text/>, содержащий XML символьные данные, которые характеризуют ошибку более детально; этот элемент должен быть связан с пространством имен 'urn:ietf:params:xml:ns:xmpp-streams' и должен иметь атрибут 'xml:lang', характеризующий язык, используемый символьными данными.

  • содержать дочерний элемент для ошибки, специфичной для определенного состояния приложения; этот элемент должен быть привязан к прикладному пространству имен, а его структура определяется этим пространством имен.

Элемент <text/> является опционным. В случае включения он должен использоваться только для описательных и диагностических данных, которые являются дополнительным пояснением условий. Он не должен интерпретироваться приложением программно. Он не должен использоваться в качестве сообщения об ошибке пользователю, но может служить дополнением к сообщению об ошибке.

4.7.3. Определенные условия

Определены следующие условия для ошибок уровня потока:

  • <bad-format/>
  • объект послал XML, который не может быть обработан; эта ошибка может использоваться вместо каких-то более специфических связанных с XML ошибок, таких как <bad-namespace-prefix/>, <invalid-xml/>, <restricted-xml/>, <unsupported-encoding/> и <xml-not-well-formed/>, хотя предпочтительнее более специфические сообщения об ошибках.
  • <bad-namespace-prefix/>
  • объект послал префикс пространства имен, которое не поддерживается, или не послал префикс пространства имен на элемент, который требует такого префикса (смотри XML имена пространства имен и префиксы (раздел 11)).
  • <conflict/>
  • сервер закрывает активный поток для этого объекта, так как инициирован новый поток, который конфликтует с существующим.
  • <connection-timeout/>
  • объект не генерировал трафик через поток в течение некоторого времени (сконфигурирован исключительно для локальной работы).
  • <host-gone/>
  • значение атрибута 'to', проверенное инициатором в заголовке потока соответствует машине, которая более не обслуживается сервером.
  • <host-unknown/>
  • значение атрибута 'to', выданное инициатором в заголовке потока, не соответствует машине, обслуживаемой сервером.
  • <improper-addressing/>
  • строфа, пересланная между серверами, не содержит атрибута 'to' или 'from' (или атрибут не имеет значения).
  • <internal-server-error/>
  • сервер имеет ошибку в конфигурации или имеет место другая внутренняя ошибка, мешающая обработке потока.
  • <invalid-from/>
  • JID имя машины, представленное в адресе 'from', не соответствует авторизованному JID или соответствующему согласованному домену (с помощью SASL или dialback).
  • <invalid-id/>
  • ID потока или dialback ID некорректны или не соответствуют присланному ранее ID.
  • <invalid-namespace/>
  • имя пространства имен потоков не соответствует "http://etherx.jabber.org/streams" или имя пространства имен dialback не совпадает с "jabber:server:dialback" (смотри "XML имена пространства имен и префиксы" (раздел 11)).
  • <invalid-xml/>
  • объект послал некорректный XML через поток серверу, который выполняет валидацию (смотри "Валидация" (раздел 11)).
  • <not-authorized/>
  • объект попытался послать данные, прежде чем поток оказался аутентифицирован, или он не авторизован для выполнения согласования формирования потока; приемник не должен обрабатывать предлагаемую строфу до посылки сообщения об ошибке.
  • <policy-violation/>
  • объект нарушил некоторые правила внутренней политики; сервер может специфицировать политику в элементе <text/>.
  • <remote-connection-failed/>
  • сервер не может корректно подключится к удаленному объекту, который необходим для авторизации или аутентификации.
  • <resource-constraint/>
  • сервер не имеет достаточных ресурсов, чтобы обслужить поток.
  • <restricted-xml/>
  • объект попытался послать нечто с ограниченным применением, например, комментарий, инструкцию обработки, DTD, ссылку на объект или недопустимый символ (смотри "Ограничения" (раздел 11)).
  • <see-other-host/>
  • сервер не будет осуществлять сервис для инициатора, но переадресует трафик другой машине; сервер должен специфицировать имя альтернативной машины или IP-адрес (который должен являться корректным доменным идентификатором) в виде элемента XML символьных данных <see-other-host/>.
  • <system-shutdown/>
  • сервер выключается и все активные потоки закрываются.
  • <undefined-condition/>
  • обстоятельства ошибки не совпадает ни с одним из перечисленных выше; это условие ошибки следует использовать только совместно с условиями специфическими для приложения.
  • <unsupported-encoding/>
  • инициатор использовал кодирование потока, которое не поддерживается сервером (смотри "Кодировка символов" (раздел 11)).
  • <unsupported-stanza-type/>
  • инициатор послал дочерний поток первого уровня, который не поддерживается сервером.
  • <unsupported-version/>
  • значение атрибута 'version', выданное инициатором в заголовке потока, специфицирует версию XMPP, которая не поддерживается сервером; сервер может специфицировать версии, поддерживаемого элемента с помощью <text/>.
  • <xml-not-well-formed/>
  • инициатор послал XML, который некорректно сформирован (смотри [XML]).

4.7.4. Специфические для приложения условия

Как было отмечено, приложение может выдать свою информацию об ошибке потока путем включения дочернего элемента ошибки. Специфический для приложения элемент должен быть дополнением к стандартному элементу. Таким образом элемент <error/> будет содержать 2-3 дочерних элементов:

<stream:error>
     <xml-not-well-formed
         xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
     <text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>
       Some special application diagnostic information!
     </text>
     <escape-your-data xmlns='application-ns'/>
   </stream:error>
   </stream:stream>

4.8. Упрощенные примеры потоков

Ниже представлены два упрощенных примера сессий, базирующихся на потоках клиент-сервер (где в "C"-строках данные пересылаются от клиента к серверу, а в "S"-строках — от сервера к клиенту); эти примеры включены для целей иллюстрации концепции, изложенной далее.

Базовая "сессия":

C: <?xml version='1.0'?>
   <stream:stream
       to='example.com'
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       version='1.0'>
S: <?xml version='1.0'?>
   <stream:stream
       from='example.com'
       id='someid'
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       version='1.0'>

... шифрование, аутентификация и подключение ресурсов ...

C:   <message from='[email protected]
'
              to='[email protected]
'
              xml:lang='en'>
C:     <body>Art thou not Romeo, and a Montague?</body>
C:   </message>
S:   <message from='[email protected]
'
              to='[email protected]
'
              xml:lang='en'>
S:     <body>Neither, fair saint, if either thee dislike.</body>
S:   </message>
C: </stream:stream>
S: </stream:stream>

Сессия реализована плохо:

C: <?xml version='1.0'?>
   <stream:stream
       to='example.com'
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       version='1.0'>
S: <?xml version='1.0'?>
   <stream:stream
       from='example.com'
       id='someid'
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       version='1.0'>

... шифрование, аутентификация и подключение ресурсов ...

C: <message xml:lang='en'>
     <body>Bad XML, no closing body tag!
   </message>
S: <stream:error>
    <xml-not-well-formed
        xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
   </stream:error>
S: </stream:stream>

5. Использование TLS

5.1. Overview

XMPP включает в себя метод обеспечения безопасности потока от фальсификации и подслушивания. Метод криптозащиты канала использует протокол безопасности транспортного уровня [TLS], с расширениями "STARTTLS", которые смоделированы для протоколов IMAP [IMAP], POP3 [POP3] и ACAP [ACAP], как это описано в RFC 2595 [USINGTLS]. Имя пространства имен для расширения STARTTLS = 'urn:ietf:params:xml:ns:xmpp-tls'.

Администратор данного домена может потребовать использования TLS для коммуникаций клиент-сервер и сервер-сервер. Клиенты должны использовать TLS, чтобы обеспечить безопасность потоков, прежде чем пытаться завершить согласование SASL (раздел 6), а серверы должны использовать TLS между двумя доменами для целей обеспечения безопасности коммуникаций сервер-сервер.

Используются следующие правила:

  1. Инициатор, который следует данной спецификации должен включить в заголовок потока атрибут 'version', содержащий значение "1.0".

  2. Если согласование TLS происходит между двумя серверами, коммуникации не должны происходить до тех пор, пока DNS не распознает имена машин, введенные серверами (смотри "Коммуникации сервер-сервер" (раздел 14)).

  3. Когда приемник, который следует данной спецификации, получает заголовок исходного потока, который содержит атрибут 'version', равный по крайней мере "1.0", он должен включить элемент <starttls/> (привязанный к пространству имен 'urn:ietf:params:xml:ns:xmpp-tls') вместе со списком других характеристик потока.

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

  5. Во время согласования использования TLS, объект не должен посылать каких-либо символов пробелов в элементе корневого потока в качестве сепараторов между элементами (любой пробел, имеющийся в примерах TLS ниже, включен исключительно из соображений читаемости); этот запрет помогает гарантировать корректность байт на уровне безопасности.

  6. Приемник должен осуществлять согласование применения TLS сразу после посылки завершающего символа ">" элемента <proceed/>. Инициатор должен осуществлять согласование применения TLS сразу после получения завершающего символа ">" элемента <proceed/> от приемника.

  7. Инициатор должен проверить сертификат, представленный приемником; (смотри "Проверка сертификата" (раздел 14)).

  8. Сертификаты должны проверяться по поводу имени машины, выданного инициатором, (например, пользователем), а не имя машины, полученное с помощью DNS; например, если пользователь специфицирует имя машины "example.com", а DNS SRV прислал "im.example.com", сертификат должен проверять версию "example.com". Если JID для любого XMPP-объекта (например, клиента или сервера) присутствует в сертификате, он должен быть представлен, в виде UTF8String в пределах имени некоторого объекта (otherName) внутри subjectAltName. Делается это с привлечением объектного идентификатора [ASN.1] "id-on-xmppAddr", специфицированного в разделе 5.

  9. Если согласование применения TLS прошло успешно, приемник должен ликвидировать любые данные, полученные ранее от инициатора небезопасным способом.

  10. Если согласование применения TLS прошло успешно, инициатор должен аннулировать любые данные, полученные ранее от приемника небезопасным способом.

  11. Если согласование применения TLS прошло успешно, приемник не должен предлагать инициатору расширения STARTTLS, а также другие возможности, которые предложены, когда поток рестартовал.

  12. Если согласование применения TLS прошло успешно, инициатор должен приступить к согласованию SASL.

  13. Если согласование применения TLS завершилось неудачей, приемник должен прервать XML-поток и разорвать TCP-соединение.

  14. По поводу механизмов, которые должны быть непременно поддержаны, смотри в "Обязательные для использования технологии" (раздел 14).

5.1.1. Идентификатор объекта ASN.1 для XMPP-адреса

Идентификатор объекта [ASN.1] "id-on-xmppAddr", описанный выше, определяется следующим образом:

id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
        dod(6) internet(1) security(5) mechanisms(5) pkix(7) }
id-on  OBJECT IDENTIFIER ::= { id-pkix 8 }  -- other name forms
id-on-xmppAddr  OBJECT IDENTIFIER ::= { id-on 5 }
XmppAddr ::= UTF8String

Этот объектный идентификатор может быть представлен в точечном формате вида "1.3.6.1.5.5.7.8.5".

5.2. Диалог

Когда инициатор обеспечивает безопасность потока с помощью TLS, реализуются следующие шаги:

  1. Инициатор открывает TCP-соединение и инициирует поток путем посылки XML-заголовка получателю. В заголовок потока вставляется атрибут 'version', со значением как минимум "1.0".

  2. Получатель откликается установлением TCP-соединения и посылкой XML-заголовка потока инициатору, включая при этом в заголовок атрибут 'version', содержащий значение как минимум "1.0".

  3. Получатель предлагает инициатору расширение STARTTLS, включив его вместе с другими возможностями потока (если для взаимодействия с получателем требуется TLS, он должен сигнализировать об этом с помощью включения элемента <required/> в качестве дочернего элемента <starttls/>).

  4. Инициатор выдает команду STARTTLS (т.е., элемент <starttls/>, соотнесенный с пространством имен 'urn:ietf:params:xml:ns:xmpp-tls'), чтобы уведомит получателя, что он хочет начать согласование применения TLS.

  5. Получатель должен откликнуться либо элементом <proceed/>, либо элементом <failure/>, соотнесенным с пространством имен 'urn:ietf:params:xml:ns:xmpp-tls'. Если произойдет сбой, получатель должен прервать XML-поток и разорвать TCP-соединение. Если все в порядке, участники должны попытаться завершить согласование применения TLS через имеющееся TCP-соединение и до завершения этого процесса не должны посылать какие-либо XML-данные.

  6. Инициатор и получатель пытаются согласно с [TLS] завершить согласование TLS.

  7. Если реализация TLS оказалась неудачной, получатель должен разорвать TCP-соединение. В случае же успеха, инициатор должен сформировать новый поток, послав открывающий XML-заголовок получателю (необязательно посылать сначала закрывающий тэг </stream>, так как получатель и инициатор должна рассматривать исходный поток закрытым после успешного завершения согласования применения TLS).

  8. После получения нового заголовка потока от инициатора, получатель должен откликнуться посылкой инициатору нового заголовка XML-потока вмести со всеми доступными возможностями (возможность STARTTLS не включается).

5.3. Пример клиент-сервер

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

Шаг 1: Клиент формирует поток к серверу:

<stream:stream
   xmlns='jabber:client'
   xmlns:stream='http://etherx.jabber.org/streams'
   to='example.com'
   version='1.0'>

Шаг 2: Сервер откликается посылкой тэга потока клиенту:

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    id='c2s_123'
    from='example.com'
    version='1.0'>

Шаг 3: Сервер посылает клиенту расширение STARTTLS и данные о механизме аутентификации и других особенностях потока:

<stream:features>
  <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
    <required/>
  </starttls>
  <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

Шаг 4: Клиент посылает серверу команду STARTTLS:

<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

Шаг 5: Сервер информирует клиента о том, что он может продолжить работу:

<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

Шаг 5 (alt): Сервер информирует клиента, что согласование TLS не состоялось и следует прервать поток и разорвать TCP-соединение:

<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
</stream:stream>

Шаг 6: Клиент и сервер пытаются завершить согласование применения TLS через существующее TCP-соединение.

Шаг 7: Если согласование TLS успешно, клиент формирует новый поток к серверу:

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>

Шаг 7 (alt): Если согласование TLS не получилось, сервер закрывает TCP-соединение.

Шаг 8: Сервер реагирует посылкой клиенту заголовка потока и любых характеристик потока:

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    from='example.com'
    id='c2s_234'
    version='1.0'>
<stream:features>
  <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>PLAIN</mechanism>
    <mechanism>EXTERNAL</mechanism>
  </mechanisms>
</stream:features>

Шаг 9: Клиент продолжает согласование SASL (раздел 6).

5.4. Пример сервер-сервер

Следующий пример показывает поток данных для двух серверов, обеспечивающих безопасность с помощью STARTTLS (заметим: альтернативные шаги, показанные ниже, приведены для иллюстрации работы протокола в случаях сбоев; они не являются обязательными).

Шаг 1: Сервер1 инициирует поток в серверу2:

<stream:stream
    xmlns='jabber:server'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>

Шаг 2: Сервер2 откликается посылкой тэга потока Серверу1:

<stream:stream
    xmlns='jabber:server'
    xmlns:stream='http://etherx.jabber.org/streams'
    from='example.com'
    id='s2s_123'
    version='1.0'>

Шаг 3: Сервер2 посылает расширение STARTTLS Серверу1 вместе с данными о механизме аутентификации и любыми другими возможностями потока:

<stream:features>
  <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
    <required/>
  </starttls>
  <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>KERBEROS_V4</mechanism>
  </mechanisms>
</stream:features>

Шаг 4: Сервер1 посылает команду STARTTLS Серверу2:

<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

Шаг 5: Сервер2 информирует Сервер1 о том, что он может продолжать работу:

<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

Шаг 5 (alt): Сервер2 информирует Сервер1 о том, что согласование применения TLS не прошло и поток закрывается:

<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
</stream:stream>

Шаг 6: Сервер1 и Сервер2 пытаются завершить согласование применения TLS через TCP.

Шаг 7: Если согласование TLS прошло успешно, Сервер1 формирует новый поток к Серверу2:

<stream:stream
    xmlns='jabber:server'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>

Шаг 7 (alt): Если согласование TLS не прошло, Сервер2 закрывает TCP-соединение.

Шаг 8: Сервер2 откликается посылкой заголовка потока Серверу1 вместе с данными о доступных возможностях потока:

<stream:stream
    xmlns='jabber:server'
    xmlns:stream='http://etherx.jabber.org/streams'
    from='example.com'
    id='s2s_234'
    version='1.0'>
<stream:features>
  <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>KERBEROS_V4</mechanism>
    <mechanism>EXTERNAL</mechanism>
  </mechanisms>
</stream:features>

Шаг 9: Сервер1 продолжает согласование применения SASL (раздел 6).

6. Использование SASL

6.1. Overview

MPP содержит в себе метод аутентификации потока с помощью XMPP-профайла протокола SASL (Simple Authentication and Security Layer) [SASL]. SASL предоставляет обобщенный метод добавления поддержки аутентификации для протоколов с установлением соединения, и XMPP использует универсальный профайл XML пространства имен для SASL, который соответствует требованиям [SASL].

Используются следующие правила:

  1. Если согласование применения SASL происходит между двумя серверами, коммуникации не должны продолжаться до тех пор, пока с помощью DNS не выяснены имена присвоенные серверам (смотри "Коммуникации сервер-сервер" (раздел 14)).

  2. Если инициатор может согласовать применение SASL, он должен включить в заголовок исходного потока атрибут 'version' со значением по крайней мере равным "1.0".

  3. Если получатель может согласовать применение SASL, он должен анонсировать один или более аутентификационных механизмов в элементе <mechanisms/>, сопряженным с пространством имен 'urn:ietf:params:xml:ns:xmpp-sasl', в отклике на открывающий тэг потока, полученный от инициатора (если открывающий тэг потока включает в себя атрибут 'version' со значением по крайней мере равным "1.0").

  4. Во время согласования применения SASL, объект не должен в качестве сепараторов элементов посылать символы пробелов (см. процедуру формирования содержимого в [XMPP-IM] и [XML]) в элементе корневого потока (любой символ пробела, представленный в примерах SASL, введен исключительно с целью обеспечения читабельности текста); этот запрет помогает гарантировать корректность представления материала на уровне безопасности.

  5. Любые XML символьные данные, содержащиеся в XML-элементах, и используемые при согласовании SASL должны иметь кодировку base64, где кодировка привязана к определениям из раздела 3 RFC 3548 [BASE64].

  6. Если предоставление "simple username" поддерживается выбранным механизмом SASL (например, это поддерживается механизмами DIGEST-MD5 и CRAM-MD5, но не поддерживается механизмами EXTERNAL и GSSAPI), во время аутентификации, инициатор должен обеспечить в качестве простого имени пользователя свой домен (IP-адрес или полное доменное имя, как оно записано в доменном идентификаторе) в случае коммуникаций сервер-сервер, или свое имя аккоунта (имя пользователя или узла, содержащегося в XMPP-идентификаторе узла) в случае коммуникаций клиент-сервер.

  7. Если инициатор хочет действовать в интересах другого объекта и выбранный механизм SASL поддерживает передачу авторизационной идентичности, инициатор должен предоставить авторизационную идентичность в процессе согласования применения SASL. Если инициатор не хочет действовать в интересах другого объекта, он не должен предоставлять идентичность авторизации. Как специфицировано в [SASL], инициатор не должен предоставлять идентичность авторизации, за исключением случая, когда идентичность авторизации отличается от идентичности по умолчанию, полученной согласно [SASL]. Если такие данные предоставляются, значение идентичности авторизации должно иметь формат <domain> (т.е., только идентификатор домена) для серверов и формат <[email protected] > (т.е., идентификатор узла и идентификатор домена) для клиентов.

  8. В случае успешного согласования SASL, которое включает в себя согласование уровня безопасности, получатель должен ликвидировать любую информацию, полученную от инициатора, которая не получена непосредственно в процессе согласования SASL.

  9. В случае успешного согласования SASL, которое включает в себя согласование уровня безопасности, инициатор должен ликвидировать любую информацию, полученную от получателя, которая не получена непосредственно в процессе согласования SASL.

  10. В отношении механизмов, которые нужно поддерживать смотри "Обязательные для использования технологии" (раздел 14).

6.2. Narrative

Когда инициатор аутентифицирует получателя, используя SASL, процедура включает в себя следующие шаги:

  1. Инициатор запрашивает аутентификацию SASL путем включения атрибута 'version' в открывающий заголовок XML потока, направленного получателю, со значением равным "1.0".

  2. После посылки заголовка XML-потока в виде отклика, получатель анонсирует список доступных механизмов аутентификации SASL; каждый из этих элементов <mechanism/> включаются в качестве дочерних в контейнерный элемент <mechanisms/>, соотнесенный с пространством имен 'urn:ietf:params:xml:ns:xmpp-sasl', который в свою очередь является дочерним элементом <features/> в пространстве имен потока. Если TLS (раздел 5) нужно установить, прежде чем использовать какой-то конкретный механизм аутентификации, получатель не должен помещать этот механизм в список механизмов аутентификации SASL, до согласования TLS. Если инициатор предоставляет корректный сертификат при предварительном согласовании TLS, получатель при согласовании SASL должен предложить инициатору механизм SASL EXTERNAL (смотри [SASL]), хотя механизм EXTERNAL может быть предложен также и при других обстоятельствах.

  3. Инициатор выбирает механизм путем посылки элемента <auth/>, соотнесенного с пространством имен 'urn:ietf:params:xml:ns:xmpp-sasl', получателю. Элемент содержит также значение атрибута 'mechanism'. Этот элемент может содержать символьные XML-данные (в терминологии SASL, "исходный отклик"), если механизм поддерживает или требует этого. Если инициатор должен послать исходный отклик нулевой длины, он должен передать отклик в виде одиночного символа равенства ("="), который указывает, что этот отклик не содержит данных.

  4. Если необходимо, получатель направляет вызов инициатору путем посылки инициатору элемента <challenge/>, соотнесенного с пространством имен 'urn:ietf:params:xml:ns:xmpp-sasl'. Этот элемент может содержать символьные данные (которые должны быть обработаны в соответствии с определением механизма SASL, который выбрал инициатор).

  5. Инициатор реагирует на вызов посылкой получателю элемента <response/>, соотнесенного с пространством имен 'urn:ietf:params:xml:ns:xmpp-sasl'. Этот элемент может содержать символьную XML-информацию (которая должна быть обработана в соответствии с определением механизма SASL, который выбрал инициатор).

  6. Если необходимо, получатель посылает несколько вызовов, а инициатор отправляет несколько откликов.

Эти последовательности вызов/отклик продолжаются до тех пор пока не случится одно из трех событий:

  1. Инициатор обрывает диалог посылкой получателю элемента <abort/>, соотносящегося с пространством имен 'urn:ietf:params:xml:ns:xmpp-sasl'. После получения элемента <abort/> получатель должен разрешить конфигурируемое но разумное число повторных попыток (по крайней мере 2), после которых он должен прервать TCP-соединение. Это позволяет инициатору (например, конечному пользователю — клиенту) перепроверить неверно выданные параметры авторизации (например, опечатку в пароле) без необходимости выполнения повторного соединения.

  2. Получатель сообщает о неудаче диалога посылкой инициатору элемента <failure/>, соотносящегося пространству имен 'urn:ietf:params:xml:ns:xmpp-sasl', конкретная причина неудачи должна быть сообщена в соответствующем дочернем элементе элемента <failure/>, как это определено главе "Ошибки SASL" (раздел 6.4). В случае неудачи получатель должен разрешить конфигурируемое, но разумное число повторных попыток (по крайней мере 2), после которых он должен прервать TCP-соединение. Это позволяет инициатору (например, конечному пользователю — клиенту) перепроверить неверно выданные параметры авторизации (например, опечатку в пароле) без необходимости выполнения повторного соединения.

  3. Получатель сообщает об успехе диалога посылкой инициатору элемента <success/>, соотносимого с пространством имен 'urn:ietf:params:xml:ns:xmpp-sasl'. Этот элемент может содержать символьную XML-информацию (в терминологии SASL "дополнительные данные при успехе"), если это требуется выбранным механизмом SASL. После получения элемента <success/> инициатор должен сформировать новый поток, путем посылки открывающего заголовка XML-потока получателю (посылать закрывающий тэг </stream> не нужно, так как приемник и инициатор должны рассматривать исходный поток закрытым после отправки или получения элемента <success/>). После получения заголовка нового потока от инициатора получатель должен реагировать посылкой инициатору нового заголовка потока и информировать партнера об имеющихся возможностях посредством элемента <features/>.

6.3. Определение SASL

Требования профайла [SASL] определяют необходимость предоставления следующей протокольной информации:

  • имя сервиса:
  • "xmpp"
  • стартовая последовательность:
  • после того как инициатор выдает открывающий заголовок потока и получатель соответственно откликается, получатель выдает список приемлемых методов аутентификации. Инициатор выбирает один из методов и посылает получателю значение атрибута 'mechanism', содержащегося в элементе <auth/>.
  • последовательность обмена:
  • вызовы и отклики реализуются посредством обмена элементами <challenge/>, направляемыми от получателя инициатору, и элементами <response/>, отправляемыми инициатором получателю. Получатель сообщает о неудаче с помощью посылки элемента <failure/>, а об успехе — посредством посылки элемента <success/>. Инициатор абортирует обмен путем посылки элемента <abort/>. После успешного согласования параметров потока, обе стороны считают исходный поток закрытым и посылают друг другу заголовки нового потока.
  • согласование на уровне безпасности:
  • уровень безопасности начинает функционировать сразу после посылки завершающего символа ">" элемента <success/> получателю, и сразу после получения инициатором завершающего символа ">" элемента <success/>.
  • использование авторизационной идентичности:
  • авторизационная идентичность может использоваться xmpp, чтобы указать <[email protected] > клиента (если это не значение по умолчанию) или посылки <domain> сервера.

6.4. Ошибки SASL

Определены следующие условия ошибок, сопряженных с SASL:

  • <aborted/>
  • Получатель подтверждает получение элемента <abort/>, посланного инициатором; посылается в ответ на элемент <abort/>.
  • <incorrect-encoding/>
  • Данные предоставленные инициатором не могут быть обработаны из-за того, что кодировка [BASE64] оказалась некорректной (например, потому что кодировка не соответствует определению в разделе 3 из [BASE64]); в ответ посылается элемент <response/> или элемент <auth/> вместе с данными исходного отклика.
  • <invalid-authzid/>
  • authzid, предоставленный инициатором, либо по причине неправильного формата, либо из-за того, что инициатор не имеет разрешения авторизовать данный идентификатор, присланный в элементах отклика <response/> или <auth/>.
  • <invalid-mechanism/>
  • Инициатор не предоставил в элементе <auth/> отклика механизма или запросил механизм, который не поддерживается получателем.
  • <mechanism-too-weak/>
  • Механизм, запрошенный инициатором, слабее предусмотренного политикой сервера для данного инициатора; присылается в элементе <response/> или <auth/> отклика.
  • <not-authorized/>
  • Аутентикация не прошла из-за того, что инициатор не предоставил корректные параметры (это может быть, например, неизвестное имя пользователя); посылается в элементах <response/> или <auth/> отклика.
  • <temporary-auth-failure/>
  • Аутентикация не прошла из-за временной ошибки на стороне получателя; посылается в в элементах <auth/> или <response/> отклика.

6.5. Пример клиент-сервер

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

Шаг 1: Клиент формирует поток до сервер:

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>

Шаг 2: Сервер реагирует посылкой клиенту тэга потока:

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    id='c2s_234'
    from='example.com'
    version='1.0'>

Шаг 3: Сервер информирует клиента об имеющихся механизмах аутентификации:

<stream:features>
  <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

Шаг 4: Клиент выбирает механизм аутентификации:

<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
      mechanism='DIGEST-MD5'/>

Шаг 5: Сервер посылает закодированный вызов [BASE64] клиенту:

<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi
LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
</challenge>

Декодированный вызов имеет вид:

realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess

Шаг 5 (alt): Сервер возвращает клиенту сообщение об ошибке:

<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
  <incorrect-encoding/>
</failure>
</stream:stream>

Шаг 6: Клиент посылает закодированный отклик [BASE64] на вызов:

<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i
T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw
MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i
LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo
YXJzZXQ9dXRmLTgK
</response>

Декодированный отклик имеет вид:

username="somenode",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
nc=00000001,qop=auth,digest-uri="xmpp/example.com",\
response=d388dad90d4bbd760a152321f2143af7,charset=utf-8

Шаг 7: Сервер посылает еще один закодированный [BASE64] вызов клиенту:

<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>

Декодированный вызов имеет вид:

rspauth=ea40f60335c427b5527b84dbabcdfffd

Шаг 7 (alt): Сервер посылалает клиенту сообщение об ошибке:

<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
  <temporary-auth-failure/>
</failure>
</stream:stream>

Шаг 8: Клиент откликается на вызов:

<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

Шаг 9: Сервер информирует клиента об успешной аутентификации:

<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

Шаг 9 (alt): Сервер информирует клиента об ошибке аутентификации:

<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
  <temporary-auth-failure/>
</failure>
</stream:stream>

Шаг 10: Клиент формирует новый поток к серверу:

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>

Шаг 11: Сервер откликается посылкой заголовка потока клиенту, сообщая о любых дополнительных имеющихся возможностях (если таких возможностей нет, посылается пустой элемент):

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    id='c2s_345'
    from='example.com'
    version='1.0'>
<stream:features>
  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
  <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</stream:features>

6.6. Пример сервер-сервер

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

Шаг 1: Сервер1 инициирует поток к Серверу2:

<stream:stream
    xmlns='jabber:server'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>

Шаг 2: Сервер2 откликается посылкой Серверу1 тэга потока:

<stream:stream
    xmlns='jabber:server'
    xmlns:stream='http://etherx.jabber.org/streams'
    from='example.com'
    id='s2s_234'
    version='1.0'>

Шаг 3: Сервер2 информирует Сервер1 о доступных механизмах аутентификации:

<stream:features>
  <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>KERBEROS_V4</mechanism>
  </mechanisms>
</stream:features>

Шаг 4: Сервер1 выбирает механизм аутентификации:

<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
      mechanism='DIGEST-MD5'/>

Шаг 5: Сервер2 посылает закодированный [BASE64] вызов Серверу1:

<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9
ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz
</challenge>

Декодированный вызов имеет вид:

realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess

Шаг 5 (alt): Сервер2 возвращает Серверу1 сообщение об ошибке:

<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
  <incorrect-encoding/>
</failure>
</stream:stream>

Шаг 6: Сервер1 посылает закодированный отклик [BASE64] на вызов:

<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
dXNlcm5hbWU9ImV4YW1wbGUub3JnIixyZWFsbT0ic29tZXJlYWxtIixub25j
ZT0iT0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5j
PTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5v
cmciLHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3
LGNoYXJzZXQ9dXRmLTgK
</response>

Дешифрованный отклик имеет вид:

username="example.org",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
nc=00000001,qop=auth,digest-uri="xmpp/example.org",\
response=d388dad90d4bbd760a152321f2143af7,charset=utf-8

Шаг 7: Сервер2 посылает еще один закодированный [BASE64] вызов Серверу1:

<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>

Декодированный вызов имеет вид:

rspauth=ea40f60335c427b5527b84dbabcdfffd

Шаг 7 (alt): Сервер2 возвращает Серверу1 сообщение об ошибке:

<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
  <invalid-authzid/>
</failure>
</stream:stream>

Шаг 8: Сервер1 откликается на вызов:

<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

Шаг 8 (alt): Сервер1 абортирует согласование:

<abort xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

Шаг 9: Сервер2 информирует Сервер1 об успешной аутентификации:

<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

Шаг 9 (alt): Сервер2 информирует Сервер1 о неудаче аутентификации:

<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
  <aborted/>
</failure>
</stream:stream>

Шаг 10: Сервер1 инициирует новый поток к Серверу2:

<stream:stream
    xmlns='jabber:server'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>

Шаг 11: Сервер2 откликается посылкой Серверу1 заголовка потока, а также данными о любых дополнительных возможностях (при отсутствии последних посылается пустой элемент):

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    from='example.com'
    id='s2s_345'
    version='1.0'>
<stream:features/>

7. Подключение ресурсов

После согласования применения SASL (раздел 6) с получателем, инициатор может хотеть или не нуждаться в подключении к потоку специфических ресурсов. В основном это относится только к клиентам: для того чтобы адаптироваться к формату адресации (раздел 3) и правил доставки строф (раздел 10), специфицированных в данном документе. Должен существовать идентификатор ресурса, ассоциированный с <[email protected] > клиента (который либо генерируется сервером, либо предлагается приложением клиента). Это гарантирует, то, что адрес используемый для данного потока, является "полным JID" формата <[email protected] /resource>.

После получения информации об успехе согласования SASL, клиент должен послать серверу новый заголовок, на который сервер должен откликнуться заголовком потока и прислать список доступных возможностей потока. Точнее, если сервер требует, чтобы клиент после успешного согласования SASL подключил ресурс к потоку, он должен включить пустой элемент <bind/>, сопряженный с пространством имен 'urn:ietf:params:xml:ns:xmpp-bind', в список возможностей, которые он предлагает клиенту после отправки заголовка для потока-отклика, посланного после успешного согласования SASL (но не до):

Сервер анонсирует возможность подключения ресурса клиенту:

<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    id='c2s_345'
    from='example.com'
    version='1.0'>
<stream:features>
  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
</stream:features>

После того как клиент оказывается проинформирован о необходимости подключения ресурса, он должен выполнить подключение ресурса к потоку, посредством посылки серверу IQ-строфы типа "set" (смотри "IQ семантика" (раздел 9)), содержащей данные, соотнесенные с пространством имен 'urn:ietf:params:xml:ns:xmpp-bind'.

Если клиент хочет позволить серверу сформировать идентификатор ресурса, он посылает IQ-строфу типа "set", которая содержит пустой элемент <bind/>:

Клиент просит сервер подключить ресурс:

<iq type='set' id='bind_1'>
  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
</iq>

Сервер, который поддерживает подключение ресурсов, должен быть способен генерировать идентификатор ресурса для клиента. Идентификатор ресурса, генерируемый сервером, должен быть уникальным для данного <[email protected] >.

Если клиент хочет специфицировать идентификатор ресурса, он посылает IQ-строфу типа "set", которая содержит желаемый идентификатор ресурса в виде текстового элемента <resource/>, который является дочерним элементом <bind/>:

Клиент подключает ресурс:

<iq type='set' id='bind_2'>
  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
    <resource>someresource</resource>
  </bind>
</iq>

Раз сервер сформировал идентификатор ресурса для клиента или воспринял идентификатор, предложенный клиентом, он должен послать клиенту IQ-строфу типа "result", которая должна содержать дочерний элемент <jid/>, который специфицирует полный JID для подключенного ресурса, как это определено сервером:

Сервер информирует клиента об успешном подключении ресурса:

<iq type='result' id='bind_2'>
  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
    <jid>[email protected]
/someresource</jid>
  </bind>
</iq>

Сервер должен воспринять идентификатор ресурса, присланный клиентом, Но может заменить его на идентификатор, сгенерированный сервером; в этом случае, сервер не должен присылать клиенту строфу ошибки (например, <forbidden/>), а вместо этого прислать клиенту свой сгенерированный идентификатор ресурса в IQ результата, как было показано выше.

Когда клиент выдает идентификатор ресурса, возможна присылка следующей строфы условий ошибки (смотри "Строфы ошибок" (раздел 9)):

  • Представленный идентификатор ресурса не может обрабатываться сервером в соответствии с Resourceprep (Приложение B).
  • Клиенту не позволяется привязывать ресурсы к потоку (например, потому, что узел или пользователь достиг предельного числа подключаемых ресурсов).
  • Предложенный идентификатор ресурса уже используется, а сервер не разрешает подключения нескольких ресурсов с одинаковыми идентификаторами.

Протокол обработки условия ошибки представлен ниже.

Идентификатор ресурса не может быть обработан при условии:

<iq type='error' id='bind_2'>
  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
    <resource>someresource</resource>
  </bind>
  <error type='modify'>
    <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

Клиент не разрешает подключение ресурса:

<iq type='error' id='bind_2'>
  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
    <resource>someresource</resource>
  </bind>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

Идентификатор ресурса уже используется:

<iq type='error' id='bind_2'>
  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
    <resource>someresource</resource>
  </bind>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

Если, до завершения этапа подключения ресурса клиент попытается послать XML-строфу, отличную от IQ-строфы с дочерним <bind/>, привязанным к пространству имен 'urn:ietf:params:xml:ns:xmpp-bind', сервер не должен обрабатывать строфу и ему следует вернуть клиенту строфу ошибки <not-authorized/>.

8. Метод сервера Dialback ("обратный дозвон")

8.1. Overview

Протоколы Jabber, которые адаптированы для XMPP, были приспособлены к использованию метода сервера "dialback" для защиты от фальсификации домена, таким образом делая сложным фальсификацию XML-строф. Обратный дозвон сервера (dialback) не является механизмом безопасности и связан исключительно со слабыми средствами верификации идентичности сервера (смотри "Коммуникации Сервер-сервер" (раздел 14), где рассмотрены характеристики безопасности этого метода). Домены, требующие надежной безопасности, должны использовать TLS и SASL. Если для аутентификации сервер-сервер используется SASL, обратный дозвон применять не следует (просто бессмысленно).

Метод обратного дозвона сервера возможен благодаря наличию DNS (Domain Name System), так как сервер может выяснить наличие другого сервера в пределах данного домена. Так как обратный дозвон зависит от DNS, междоменные коммуникации не должны запускаться, пока объекты не будут локализованы с помощью DNS сервера (смотри раздел 14)).

Обратный дозвон сервера является однонаправленным, по этой причине обеспечивает слабую верификацию идентичности для потока лишь в одном направлении. Так как обратный дозвон сервера не является механизмом аутентификации, двухсторонняя аутентификация здесь невозможна. Следовательно, чтобы реализовать двунаправленный обмен между доменами, обратный дозвон должен быть выполнен для обоих направлений.

Метод генерации и верификации ключей, используемый в dialback сервером должен учитывать используемые имена машин, идентификатор потока, формируемый сервером-приемником и секретный ключ, известный всем авторизованным в сети серверам. Идентификатор потока является критическим параметром безопасности в процедуре dialback и, следовательно, должен быть непредсказуемым и неповторимым (смотри [RANDOM]).

Любая ошибка, которая происходит во время согласования dialback должна рассматриваться как ошибка потока, которая приводит к прерыванию потока и разрыву TCP-соединения. Возможные условия ошибки специфицированы ниже в описании протокола.

Здесь используется следующая терминология:

  • Originating Server — исходный сервер
  • сервер, который пытается установить соединение между двумя доменами.
  • Receiving Server — принимающий сервер
  • сервер, который пытается проверить, что исходный сервер представляет тот самый домен, который он анонсирует.
  • Authoritative Server — управляющий сервер
  • сервер, который отвечает, руководствуясь именем, введенным исходным сервером; для базовой конфигурации это исходный сервер, но может быть и другая машина в сети исходного сервера.

8.2. Порядок событий

Ниже представлено краткое описание последовательности событий при dialback:

  1. Исходный сервер устанавливает соединение с принимающим сервером.
  2. Исходный сервер посылает через соединение значение 'key' принимающему серверу.
  3. Принимающий сервер устанавливает соединение с управляющим сервером.
  4. Принимающий сервер посылает этот ключ управляющему серверу.
  5. Управляющий сервер подтверждает или не подтверждает корректность ключа.
  6. Принимающий сервер информирует исходный сервер, аутентифицирован он или нет.

Мы можем представить схему диалога следующим образом:

Originating               Receiving
  Server                    Server
-----------               ---------
    |                         |
    |   establish connection  |
    | ----------------------> |
    |                         |
    |   send stream header    |
    | ----------------------> |
    |                         |
    |   send stream header    |
    | <---------------------- |
    |                         |                   Authoritative
    |   send dialback key     |                       Server
    | ----------------------> |                   -------------
    |                         |                         |
                              |   establish connection  |
                              | ----------------------> |
                              |                         |
                              |   send stream header    |
                              | ----------------------> |
                              |                         |
                              |   send stream header    |
                              | <---------------------- |
                              |                         |
                              |   send verify request   |
                              | ----------------------> |
                              |                         |
                              |   send verify response  |
                              | <---------------------- |
                              |
    |  report dialback result |
    | <---------------------- |
    |                         |

8.3. Протокол

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

  1. Исходный сервер устанавливает ТСР-соединение с принимающим сервером.

  2. Исходный сервер посылает заголовок потока принимающему серверу:

    <stream:stream
        xmlns:stream='http://etherx.jabber.org/streams'
        xmlns='jabber:server'
        xmlns:db='jabber:server:dialback'>

    Заметим: атрибуты 'to' и 'from' являются опционными для элемента корневого потока. Включение декларации пространства имен xmlns:db с приведенным именем указывает принимающему серверу, что исходный сервер поддерживает dialback. Если имя пространства имен некорректно, тогда принимающий сервер должен сформировать ошибку потока <invalid-namespace/> и завершить XML-поток, а также разорвать TCP-соединение.

  3. Принимающий сервер должен отослать назад заголовок потока исходному серверу, включая уникальный ID этого взаимодействия:

    <stream:stream
        xmlns:stream='http://etherx.jabber.org/streams'
        xmlns='jabber:server'
        xmlns:db='jabber:server:dialback'
        id='457F9224A0...'>

    Заметим: Если имя пространства имен некорректно, тогда исходный сервер должен сформировать ошибку потока <invalid-namespace/>, прервать поток и разорвать TCP-соединение. Принимающий сервер должен ответить, но может молча завершить XML-поток, в зависимости от принятой политики безопасности; однако, если принимающий сервер хочет продолжить, он должен послать исходному серверу заголовок потока.

  4. Исходный сервер посылает ключ dialback принимающему серверу:

    <db:result
        to='Receiving Server'
        from='Originating Server'>
      98AF014EDC0...
    </db:result>

    Замечание: Этот ключ не просматривается принимающим сервером, так как он не хранит информацию об исходном сервере по завершении сессии. Ключ, генерируемый исходным сервером, должен базироваться частично на значении ID, предоставленном принимающим сервером на предыдущем шаге, а также частично на секретном ключе, совместно используемом исходным и управляющим серверами. Если значение адреса 'to' не соответствует имени машины, распознанному принимающим сервером, тогда последний должен генерировать сообщение ошибки потока <host-unknown/> и прерывать XML-поток. Если значение адреса 'from' соответствует домену, с которым принимающий сервер уже установил соединение, тогда он должен поддерживать существующее соединение до тех пор, пока не будет установлено новое соединение. Кроме того, принимающий сервер может сформировать сообщение об ошибке потока <not-authorized/> для нового соединения и затем прервать XML-поток и его TCP-соединение, связанные с новым запросом.

  5. Принимающий сервер устанавливает TCP-соединение с доменным именем, представленным исходным сервером, как результ установления соединения с управляющим сервером.

  6. Принимающий сервер посылает заголовок потока управляющему серверу:

    <stream:stream
        xmlns:stream='http://etherx.jabber.org/streams'
        xmlns='jabber:server'
        xmlns:db='jabber:server:dialback'>

    Замечание: атрибуты 'to' и 'from' являются опционными для элемента корневого потока. Если имя пространства имен некорректно, тогда управляющий сервер должен генерировать сообщение ошибки потока <invalid-namespace/> и прерывать XML-поток и TCP-соединение.

  7. Управляющий сервер посылает заголовок потока принимающему серверу:

    <stream:stream
        xmlns:stream='http://etherx.jabber.org/streams'
        xmlns='jabber:server'
        xmlns:db='jabber:server:dialback'
        id='1251A342B...'>

    Замечание: Если имя пространства имен некорректно, тогда принимающий сервер должен сформировать сообщение ошибки потока <invalid-namespace/> и прервать XML-поток и соответствующее TCP-соединение между ним и сервером управления. Если ошибка потока случится между принимающим и управляющим серверами, тогда принимающий сервер должен сформировать сообщение об ошибке потока <remote-connection-failed/> и прервать поток и ТСР-соединение с исходным сервером.

  8. Принимающий сервер посылает управляющему серверу запрос верификации ключа:

    <db:verify
        from='Receiving Server'
        to='Originating Server'
        id='457F9224A0...'>
      98AF014EDC0...
    </db:verify>

    Замечание: Здесь уже получены имена машин, оригинальный идентификатор из заголовка потока принимающего сервера исходному серверу на шаге 3, и ключ, который исходный сервер послал принимающему серверу на шаге 4. На основе этой информации, а также на секретном, совместно используемом ключе сети управляющего сервера ключ верифицируется. Для генерации ключа может использоваться любой метод верификации. Если значение адреса 'to' не соответствует имени машины, выявленному управляющим сервером, тогда управляющий сервер должен сформировать сообщение об ошибке потока <host-unknown/> и разорвать XML-поток и ТСР-соединение. Если значение адреса 'from' не соответствует имени машины, представленному принимающим сервером при открытии TCP-соединения, тогда управляющий сервер должен сформировать ошибку потока <invalid-from/>.

  9. Управляющий сервер проверяет, является ли ключ корректным:

    <db:verify
        from='Originating Server'
        to='Receiving Server'
        type='valid'
        id='457F9224A0...'/>

    или

    <db:verify
        from='Originating Server'
        to='Receiving Server'
        type='invalid'
        id='457F9224A0...'/>

    Замечание: Если ID не соответствует тому, который предложен принимающим сервером на шаге 3, тогда принимающий сервер должен сгенерировать ошибку потока <invalid-id/> и прервать XML-поток и соответствующее TCP-соединение. Если значение адреса 'to' не соответствует имени машины, распознанному принимающим сервером, тогда принимающий сервер должен выработать ошибку потока <host-unknown/> и разорвать TCP-соединение. Если значение адреса 'from' не соответствует имени машины, представленному исходным сервером при открытии TCP-соединения, тогда принимающий сервер должен выработать ошибку потока <invalid-from/> и разорвать TCP-соединение. После возвращения флага верификации принимающему серверу, управляющий сервер должен прервать поток между ними.

  10. Принимающий сервер информирует исходный сервер о результате:

    <db:result
        from='Receiving Server'
        to='Originating Server'
        type='valid'/>

    Замечание: В этой точке, соединение либо верифицировано type='valid', либо объявлено некорректным. Если соединение некорректно, принимающий сервер должен прервать XML-поток и разорвать TCP-соединение. Если соединение верифицировано, исходный сервер начинает посылать данные, которые читаются принимающим сервером; перед этим все XML-строфы, посланные принимающему серверу должны быть молча отброшены.

Результатом всего предшествующего является то, что принимающий сервер проверил идентичность исходного сервера, таким образом управляющий сервер может посылать, а принимающий сервер принимать XML-строфы через "исходный поток" (т.е., поток от исходного к принимающему серверу). Для того чтобы верифицировать идентичности объектов, используя "поток-отклик" (т.е., поток от принимающего сервера к исходному серверу), должен быть осуществлен также dialback ("обратный дозвон") в обратном направлении.

После успешного выполнения процедуры dialback, принимающий сервер должен воспринять последующие пакеты <db:result/> (например, запросы валидации, посланные субдомену или другой машине, обслуживаемой принимающим сервером) от исходного сервера через имеющееся верифицированное соединение.

Даже если согласование dialback успешно, сервер должен проверить, что все XML-строфы полученные от другого сервера содержат атрибуты 'from' и 'to'; если строфа не следует этому ограничению, сервер, который получает строфу должен сформировать сообщение об ошибке потока <improper-addressing/> и разорвать TCP-соединение. Кроме того, сервер должен проверить, что атрибут 'from' строфы, полученной от другого сервера, содержит верифицированное имя домена для потока; если строфа не отвечает этим ограничениям, сервер, который получает строфу, должен сформировать ошибку потока <invalid-from/> и разорвать соединение.

9. XML-строфы

После согласования применения TLS (раздел 5), SASL (раздел 6) и подключения ресурсов (раздел 7), если требуется, можно начать пересылку через поток XML-строф. Определены три типа XML-строф для пространств имен 'jabber:client' и 'jabber:server': <message/>, <presence/> и <iq/>. Кроме того, существует пять общих атрибутов для трех видов строф. Ниже описаны эти общие атрибуты, так же как базовая семантика трех видов строф, более детальную информацию о синтаксисе XML-строф и их применении можно найти в [XMPP-IM].

9.1. Общие атрибуты

Следующие пять атрибутов являются общими для сообщений, данных о присутствии и IQ-строф:

9.1.1. Атрибут 'to'

Атрибут 'to' специфицирует JID получателя строфы.

В пространстве имен 'jabber:client', строфа должна иметь атрибут 'to', хотя строфа, посланная от клиента серверу, для обработки сервером (например, данные о присутствии, посланные серверу для широковещательной рассылки другим объектам) не должна содержать атрибут 'to'.

В пространстве имен 'jabber:server' строфа должна иметь атрибут 'to'; если сервер получает строфу, которая не отвечает этим ограничениям, он должен сформировать ошибку потока <improper-addressing/> и разорвать соединение.

Если значение атрибута 'to' некорректно, объект, выяснивший этот факт, должен вернуть соответствующую ошибку отправителю, установив атрибут 'from' строфы-ошибки равной содержимому атрибуту 'to' исходной строфы.

9.1.2. Атрибут 'from'

Атрибут 'from' специфицирует JID отправителя.

Когда сервер получает XML-строфа в контексте аутентифицированного потока, сопряженного с пространством имен 'jabber:client', он должен сделать следующее:

  1. проверить, что значение атрибута 'from', предложенное клиентом, соответствует подключенному ресурсу для ассоциированного объекта
  2. добавить адрес 'from' к строфе, чье значение равно чистому JID (<[email protected] >) или полный JID (<[email protected] /resource>), определенный сервером для подключенного ресурса, который сформировал строфу (смотри "Определение адресов" (раздел 3))

Если клиент пытается послать XML-строфу, для которой значение атрибута 'from' не соответствует одному из подключенных ресурсов для данного объекта, сервер должен прислать клиенту ошибку потока <invalid-from/>. Если клиент пытается послать XML-строфу через поток, который еще не аутентифицирован, сервер должен вернуть клиенту ошибку потока <not-authorized/>. Если имеют место оба эти условия, со соединение прерывается. Это помогает исключить атаку отказа в обслуживании, запущенную недобросовестным клиентом.

Когда сервер генерирует строфу от своего имени для доставки подключенному клиенту (например, в контексте сервиса памяти, предоставляемого сервером клиенту), строфа либо не должна включать в себя атрибут 'from' либо включать атрибут 'from', чье значение является чистым JID аккоунта (<[email protected] >) или полным JID клиента (<[email protected] /resource>). Сервер не должен посылать клиенту строфу без атрибута 'from', если строфа не была сформирована самим сервером. Когда клиент получает строфу, которая не содержит атрибута 'from', он должен полагать, что строфа пришла от сервера, с которым клиент соединен.

В пространстве имен 'jabber:server', строфа должна иметь атрибут 'from'; если сервер получает строфу, которая не отвечает этому ограничению, он должен генерировать ошибку потока <improper-addressing/>. Кроме того, секция доменного идентификатора JID, содержащаяся в атрибуте 'from', должна соответствовать имени машины отправляющего сервера (или любой проверенный домен, такой как субдомен сервера-отправителя). Если сервер получает строфу, которая не отвечает этому ограничению, он должен сформировать сообщение об ошибке <invalid-from/>.

9.1.3. Атрибут 'id'

Опционный атрибут 'id' может использоваться объектом-отправителем для внутреннего отслеживания строф, которые он отправляет и получает (в частности для отслеживания взаимодействий типа запрос-отклик, типичных для семантики IQ-строф). Для атрибута 'id' глобальная уникальность является опционной в рамках домена или потока.

9.1.3. Атрибут 'type'

Атрибут 'type' специфицирует данные о целях или контексте сообщения, данные о присутствии или IQ-строфы. Конкретные допустимые значения атрибута 'type' сильно зависят от того, является ли строфа сообщением, данными о присутствии или IQ. Значения для строф сообщений и данных о присутствии являющиеся специфичными для технологии сообщений реального времени, они описаны в [XMPP-IM], тогда как значения для IQ-строф специфицируют роль IQ-строф в структурированном диалоге запрос-отклик (раздел 9). Единственным общим для всех трех типов строф является ошибка; смотри "Ошибки строф" (раздел 9).

9.1.5. Атрибут 'xml:lang'

Строфа должна иметь атрибут 'xml:lang' (как это описано в разделе 2.12 [XML]), если строфа содержит символьные данные, которые предназначены для обычного пользователя-человека (как описано в RFC 2277 [CHARSET], "Интернационализация для людей"). Значение атрибут 'xml:lang' специфицирует язык по умолчанию любых символьных данных, которое может быть переписано атрибутом 'xml:lang' дочернего элемента. Если строфа не имеет атрибута 'xml:lang', реализация должна предполагать, что действует значение языка по умолчанию, специфицированное для потока, как это определено выше в раздел 4. Значение атрибута 'xml:lang' должно быть NMTOKEN и должно соответствовать формату, определенному в RFC 3066 [LANGTAGS].

9.2. Базовая семантика

9.2.1. Семантика сообщений

Тип строф <message/> можно рассматривать как "push"-механизм, поскольку один объект "проталкивает" информацию другому объекту, подобно коммуникациям, которые осуществляются в системах типа электронной почты. Все строфы сообщений имеют атрибут 'to', который специфицирует получателя сообщения. После получения такой строфы сервер должен переадресовать или доставить ее адресату (смотри "Серверные правила для обработки XML-строф" (раздел 10)).

9.2.2. Семантика присутствия

Элемент <presence/> может рассматриваться как механизм широковещательного уведомления, посредством чего многие объекты получают информацию об объекте, на которую они подписались (в данном случае информация о доступности сети). Вообще, уведомляющий объект должен послать строфу присутствия без атрибута 'to', серверу, который должен широковещательно переслать ее всем объектам-подписчикам. Однако уведомляющий объект может также послать строфу присутствия с атрибутом 'to', в этом случае сервер должен обеспечить доставку строфы конкретному адресату. Общие правила переадресации и доставки строф смотри в главе "Серверные правила обработки XML-строф" (раздел 10) и в [XMPP-IM].

9.2.3. Семантика IQ

Info/Query, или IQ, представляет собой механизм запросов-откликов, сходный в некотором роде с [HTTP]. Семантика IQ делает возможными для объекта отправку запросов и получение откликов другого объекта. Информационное содержание запроса и отклика определяется декларацией пространства имен дочернего объекта IQ-элемента, а диалог отслеживается запрашивающим объектом с помощью атрибута 'id'. Таким образом, за стандартным обменом структурированными данными, такими как get/result или set/result следует IQ-диалог (хотя в отклике на запрос при определенных условиях может быть прислано сообщение об ошибке):

Requesting                 Responding
  Entity                     Entity
----------                 ----------
    |                           |
    | <iq type='get' id='1'>    |
    | ------------------------> |
    |                           |
    | <iq type='result' id='1'> |
    | <------------------------ |
    |                           |
    | <iq type='set' id='2'>    |
    | ------------------------> |
    |                           |
    | <iq type='error' id='2'>  |
    | <------------------------ |
    |                           |

Для того чтобы усилить данную семантику, применены следующие правила:

  1. Для IQ-строф необходим атрибут 'id'.

  2. Для IQ-строф необходим атрибут 'type'. Значение должно быть из числа перечисленных ниже.

    • get
    • строфа является запросом информации или требований.
    • set
    • строфа предоставляет необходимые данные, устанавливает новые значения или замещает существующие величины.
    • result
    • строфа является откликом на успешный запрос get или set.
    • error
    • произошла ошибка, связанная с обработкой или доставкой выданной перед этим строфы (get или set). (смотри "Строфы ошибок" (раздел 9)).
  3. Объект, который получает IQ-запрос типа "get" или "set" должен ответит IQ-откликом типа "result" или "error" (отклик должен сохранить атрибут 'id' запроса).

  4. Объект, который получает строфу типа "result" или "error" не должен откликаться на строфу посылкой следующего IQ-отклика типа "result" или "error"; однако, как показано выше, запрашивающий объект может послать еще один запрос (например, IQ типа "set" для того чтобы предоставить нужную информацию, выявленную в результате обмена get/result).

  5. IQ-строфа типа "get" или "set" должна содержать один и только один дочерний элемент, который специфицирует семантику конкретного запроса или отклика.

  6. IQ-строфа типа "result" должна содержать нуль или один дочерний элемент.

  7. IQ-строфа типа "error" должна содержать дочерний элемент, содержащийся в соответствующем "get" или "set" и должна включать в себя дочерний элемент <error/>. Подробности смотри в главе "ошибки строф" (раздел 9).

9.3. Ошибки строф

Ошибки, сопряженные со строфами обрабатываются аналогично ошибкам потока (раздел 4). Однако, в отличии от ошибок потока, ошибки строф являются исправимыми; следовательно ошибки строф содержат намеки на действия, которые следует предпринять исходному отправителю, для того чтобы исправить ошибку.

9.3.1. Правила

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

  • Принимающий или обрабатывающий объект, который детектирует состояние ошибки в отношении строфы, должен прислать отправителю строфу того же сорта (сообщение, присутствие или IQ), чей атрибут 'type' установлен равным "error" (такая строфа называется "строфой ошибки").

  • Объект, который генерирует строфу ошибки должен включить исходный посланный XML, так чтобы отправитель мог проверить, если необходимо, корректность XML, прежде чем предпринимать попытку повторной передачи.

  • Строфа-ошибка должна содержать дочерний элемент <error/>.

  • Дочерний элемент <error/> не должен включаться, если атрибут 'type' имеет значение, отличное от "error" (или если атрибута 'type' нет вообще).

  • Объект, который получает ошибку строфы, не должен реагировать на строфу с еще одной ошибкой; это предотвращает зацикливание.

9.3.2. Синтаксис

<stanza-kind to='sender' type='error'>
  [RECOMMENDED to include sender XML here]
  <error type='error-type'>
    <defined-condition xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'
          xml:lang='langcode'>
      OPTIONAL descriptive text
    </text>
    [OPTIONAL application-specific condition element]
  </error>
</stanza-kind>

Вид строфы может принимать значение message (сообщение), presence (присутствие) или iq.

Значение элемента <error/> атрибута 'type' должно принимать одно из следующих значений:

  • cancel
  • не предпринимать повторных попыток (ошибка неисправима)
  • continue
  • продолжать (это всего лишь предупреждение)
  • modify
  • повторить попытку после изменения посылаемых данных
  • auth
  • повторить попытку после изменения параметров авторизации
  • wait
  • повторить поытку после выдержки (ошибка является временной)

Элемент <error/>:

  • должен содержать дочерний элемент, соответствующий одному из условий, специфицированных ниже; этот элемент должен соотноститься с пространством имен 'urn:ietf:params:xml:ns:xmpp-stanzas'.

  • Может содержать дочерний элемент <text/>, который несет в себе символьные XML-данные, которые описывают ошибку более детально. Этот элемент должен соотноситься с пространством имен 'urn:ietf:params:xml:ns:xmpp-stanzas' и должен иметь атрибут 'xml:lang'.

  • Может содержать дочерний элемент для ошибок, специфических для приложения; этот элемент должен соотноситься с пространством имен приложения, а его структура определяется этим пространством имен.

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

Наконец, для обеспечения обратной совместимости, схема (специфицированная в [XMPP-IM]) позволяет опционное включение атрибута 'code' элемента <error/>.

9.3.3. Определенные условия

Определены следующие условия использования ошибок строф.

  • <bad-request/>
  • отправитель послал XML с некорректным форматом или который не может быть обработан (например, IQ-строфа, которая включает в себя нераспознаваемое значение атрибут 'type'); сопряженным типом ошибки должен быть "modify".
  • <conflict/>
  • доступ не может быть предоставлен, так как существует ресурс или сессия с тем же именем или адресом; сопряженным типом ошибки должен быть "cancel".
  • <feature-not-implemented/>
  • запрошенная возможность не реализуется получателем или сервером и, следовательно, не может быть осуществлена; сопряженным типом ошибки должен быть "cancel".
  • <forbidden/>
  • запрошенный объект не имеет требующегося разрешения для выполнения данного действия; cопряженным типом ошибки должен быть "auth".
  • <gone/>
  • получатель или сервер не может более контактировать с этим адресом (строфа ошибки может содержать новый адрес в виде символьных XML-данных элемента <gone/>); cопряженным типом ошибки должен быть "modify".
  • <internal-server-error/>
  • сервер не может обработать строфу, из-за неверной конфигурации или неопределенной внутренней ошибки сервера; cопряженным типом ошибки должен быть "wait".
  • <item-not-found/>
  • адресованный JID или запрошенный элемент не может быть найден; cопряженным типом ошибки должен быть "cancel".
  • <jid-malformed/>
  • посылающий объект предоставил или переслал XMPP-адрес (например, значение атрибута 'to' ) или нечто в этом же роде (например, идентификатор ресурса), который не стыкуется с синтаксисом, определенным в главе "Схема адресации" (раздел 3); cопряженным типом ошибки должен быть "modify".
  • <not-acceptable/>
  • получатель или сервер понимает запрос, но отказывается обрабатывать его, так как он не отвечает критериям, определенным получателем или сервером (например, локальная политика в отношении приемлемых слов в сообщениях); cопряженным типом ошибки должен быть "modify".
  • <not-allowed/>
  • получатель или сервер не позволяют любому объекту выполнять операцию; cопряженным типом ошибки должен быть "cancel".
  • <not-authorized/>
  • отправитель должен предоставить правильные параметры авторизации, прежде чем ему будет позволено выполнить соответствующеие действия, или он выдал неверные параметры авторизации; cопряженным типом ошибки должен быть "auth".
  • <payment-required/>
  • запрашивающий объект не авторизован для доступа к запрашиваему сервису, так как требуется оплата; cопряженным типом ошибки должен быть "auth".
  • <recipient-unavailable/>
  • адресат временно недоступен; cопряженным типом ошибки должен быть "wait" (заметим: приложение не должно возвращать эту ошибку, если, делая это, выдаст информацию о сетевой доступности адресата объекту, неавторизованному для получения такой информации).
  • <redirect/>
  • получатель или сервер переадресуют запрос для этой информации другому объекту, обычно временно (ошибочная строфа должна содержать альтернативный адрес, который должен быть корректным JID, в текстовом элементе <redirect/> ); cопряженным типом ошибки должен быть "modify".
  • <registration-required/>
  • запрашиваемый объект не авторизован для доступа к запрошенному сервису, так как требуется регистрация; cопряженным типом ошибки должен быть "auth".
  • <remote-server-not-found/>
  • удаленный сервер или сервис, специфицированный в качестве части или всего JID получателя, не существует; cопряженным типом ошибки должен быть "cancel".
  • <remote-server-timeout/>
  • удаленный сервер или сервис, специфицированный в качестве части или всго JID получателя, не досягаемы в пределах разумного времени; cопряженным типом ошибки должен быть "wait".
  • <resource-constraint/>
  • получатель или сервер имеют мало системных ресурсов для обслуживания запроса; cопряженным типом ошибки должен быть "wait".
  • <service-unavailable/>
  • получатель или сервер в настоящее время не предоставляют запрашиваемого сервиса; cопряженным типом ошибки должен быть "cancel".
  • <subscription-required/>
  • запрашиваемый объект не авторизован для доступа к запрашиваемого сервиса, так как требуется подписка; cопряженным типом ошибки должен быть "auth".
  • <undefined-condition/>
  • условие ошибки не совпадает ни с одним, описанным в этом перчне; любой тип ошибки может быть ассоциирован с этим условием, и это условие может использоваться только совместно с условием, специфичным для приложения.
  • <unexpected-request/>
  • получатель или сервер понимают запрос, но не ожидали его в данный момент; cопряженным типом ошибки должен быть "wait".

9.3.4. Условия специфические для приложения

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

<iq type='error' id='some-id'>
  <error type='modify'>
    <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <too-many-parameters xmlns='application-ns'/>
  </error>
</iq>
<message type='error' id='another-id'>
  <error type='modify'>
    <undefined-condition
          xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <text xml:lang='en'
          xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>
      Some special application diagnostic information...
    </text>
    <special-application-condition xmlns='application-ns'/>
  </error>
</message>

10. Правила сервера для обработки XML-строф

Адаптивные реализации сервера должны гарантировать надлежащую обработку XML-строф между любыми двумя объектами.

За пределами требований нормальной обработки реализация каждого сервера будет содержать свои собственные "деревья доставки" для обслуживания приходящих к ним строф. Такое дерево определяет, нуждается ли строфа в переадресации в другой домен, будет ли обработана локально или доставлена ресурсу, сопряженному с соседним узлом. Здесь используются следующие правила:

10.1. Нет адреса 'to'

Если строфа не имеет атрибута 'to', сервер должен обработать ее для объекта, ее пославшего. Так как все строфы, полученные от других серверов, должны иметь атрибут 'to', это правило приложимо только к строфам, полученных от зарегистрированных объектов (таких как клиент), т.е. подключенных к серверу. Если сервер получает строфу присутствия без атрибута 'to', сервер должен послать ее широковещательно объектам, которые подписаны на посылку данных присутствия, если это возможно (семантика широковещательных данных для обмена сообщениями и данными присутствия определена в [XMPP-IM]). Если сервер получает IQ-строфу типа "get" или "set" без атрибута 'to' и он понимает пространство имен, которое соотнесено с содержимым строфы, он должен либо обработать строфу от имени отправителя (где под словом "обработать" подразумевается семантика соответствующего пространства имен) или прислать отпраителю сообщение об ошибке

10.2. Чужой домен

Если имя машины секции идентификатора домена JID содержит атрибут 'to', который не согласуется со сконфигурированными именами самого сервера или субдомена, сервер должен переадресовать строфу внешнему домену. Возможны два случая:

Между двумя доменами уже имеется поток сервер-сервер: существуют маршруты строф сервера к управляющему серверу для внешнего домена через существующий поток.

Между двумя доменами не существует потока сервер-сервер:

  1. выясняет имя машины для внешнего домена (как это определено для коммуникаций сервер-сервер (раздел 14)),
  2. согласует поток сервер-сервер между двумя доменами (как это определено для применения TLS (раздел 5) и использует SASL (раздел 6)), и
  3. переадресует строфу управляющему серверу для внешнего домена через вновь созданный поток.

Если маршрутизация до сервера получателя не удалась, сервер должен прислать сообщение об ошибке отправителю; если сервер получателя достижим, но доставка строфы сервером получателя невозможна, сервер получателя должен прислать сообщение ошибки отправителю.

10.3. Субдомен

Если имя машины секции идентификатора домена JID, содержащегося в атрибуте 'to', соответствует субдомену одного из сконфигурированных имен самого сервера, сервер должен либо обработать строфу сам, либо переадресовать ее специализированному сервису, который ответственен за субдомен (если субдомен сконфигурирован), или послать уведомление об ошибке отправителю (если субдомен не сконфигурирован).

10.4. Полный домен или специфические ресурсы

Если имя машины секции идентификатора домена JID, содержащегося в атрибуте 'to', соответствует сконфигурированному имени самого сервера, а JID, содержащий атрибут 'to', имеет формат <domain> или <domain/resource>, сервер (или определенный ресурс) должен либо обрабатывать строфу или возвращать отправителю ошибку.

10.5. Узел в том же домене

Если имя машины секции идентификатора домена JID, содержащееся в атрибуте 'to', соответствует субдомену одного из сконфигурированных имен самого сервера, а JID, содержащий атрибут 'to', имеет формат <[email protected] > или <[email protected] /resource>, сервер должен доставить строфу адресату строфы, согласно JID, содержащемуся в атрибуте 'to'. Используются следующие правила:

  1. Если JID содержит идентификатор ресурса (т.е., имеет форму <[email protected] /resource>) и существует подключенный ресурс, который соответствует полному JID, сервер получателя должен вставить строфу в поток или сессию, которая соответствует идентификатору ресурса.

  2. Если JID содержит идентификатор ресурса и не существует подключенного ресурса, который соответствует полному JID, сервер получателя должен прислать отправителю ошибку строфы <service-unavailable/>.

  3. Если JID имеет формат <[email protected] > и в узле существует, по крайней мере, один подключенный ресурс, сервер получателя должен доставить строфу одному из подключенных ресурсов, согласно правилам приложения (набор правил доставки сообщения и данных о положении определен в [XMPP-IM]).

11. Использование XML в XMPP

11.1. Ограничения

XMPP является упрощенным и специализированным протоколом для потоковых элементов XML, для того чтобы обмениваться структурированной информацией в режиме близком к реальному времени. Так как XMPP не требует парсинга произвольных XML-документов, не существует никаких требований, которые должен поддерживать XMPP [XML]. В частности, используются следующие ограничения.

Что касается XML-генерации, XMPP-реализации не должны вводить в XML-поток следующие вещи:

  • комментарии (как это определено в разделе 2 [XML])
  • инструкции обработки (раздел 2)
  • внутренние или внешние DTD-субнаборы (раздел 2)
  • внутренние или внешние ссылки на объекты (раздел 4) за исключением заранее определенных сущностей (раздел 4)
  • символьные данные или значения атрибута, содержащие символы без эскэйпов, которые могут указывать на предопределенные объекты (раздел 4); следует избегать использования таких символов

С учетом XML-обработки, если XMPP-реализация получает такие запрещенные данные, она должна их игнорировать.

11.2. Имена XML-пространства имен и префиксов

Пространство имен XML [XML-NAMES] используется в рамках XMPP-подобных XML, чтобы сформировать четкие границы принадлежности данных. Основной функцией пространства имен является разделение различных словарей XML-элементов, которые структурно перемешаны. Гарантия того, что XMPP-подобные XML знакомы с пространством имен, делает возможным структурное перемешивание любых допустимых XML с любыми элементами данных в рамках XMPP. Правила для пространства имен XML и префиксов определены в следующих подразделах.

11.2.1. Пространство имен потоков

Декларацией пространства имен потока для всех заголовков XML-потока является обязательной. Имя пространства имен потока должно быть 'http://etherx.jabber.org/streams'. Элемент имен элемента <stream/> и его дочерних элементов <features/> и <error/> должны быть заданы во всех случаях префиксом пространства имен потоков. Реализация должна генерировать для этих элементов только префикс 'stream:'.

11.2.2. Пространство имен по умолчанию

Декларациея пространства имен по умолчанию является обязательной, она используется во всех XML-потоках, для того чтобы определить для корневого потока допустимые дочерние элементы первого уровня. Эта декларация пространства имен должна быть идентичной для исходного потока и для потока-отклика, так чтобы оба потока были совместимыми. Декларация пространства имен по умолчанию применяется для потока и всех строф, посланных в рамках потока.

Реализация сервера должна поддерживать следующие два пространства имен по умолчанию:

  • jabber:client
  • это пространство имен по умолчанию декларируется, когда поток используется для коммуникаций между клиентом и сервером.
  • jabber:server
  • это пространство имен по умолчанию декларируется, когда поток используется для коммуникаций между двумя серверами.

Реализация клиента должна поддерживать пространство имен по умолчанию 'jabber:client'.

Реализация не должна генерировать префиксы пространства имен для элементов в пространстве имен по умолчанию, если это пространство имен 'jabber:client' или 'jabber:server'. Реализация не должна генерировать префиксов пространства имен для элементов, квалифицируемых по содержанию (в противоположность потоку) пространства имен, отличного от 'jabber:client' и 'jabber:server'.

Замечание: Пространства имен 'jabber:client' и 'jabber:server' являются почти идентичными, но используются в различных контекстах (коммуникации клиент-сервер для 'jabber:client' и коммуникации сервер-сервер для 'jabber:server'). Единственное отличие между ними заключается в том, что атрибуты 'to' и 'from' являются опционными для строф, посланных в рамках 'jabber:client', в то время как они обязательны для строф, посланных в рамках 'jabber:server'. Если реализация принимает поток, который соотносится с пространствами имен 'jabber:client' или 'jabber:server', она должна поддерживать общие атрибуты (раздел 9) и базовую семантику (раздел 9) всех трех главных видов строф (сообщение, присутствие и IQ).

11.2.3. Пространство имен Dialback

Декларация пространства имен dialback является обязательной для всех элементов, используемых в серверном dialback (раздел 8). Имя пространства имен dialback должно быть 'jabber:server:dialback'. Все элементы, соотнесенные с этим пространством имен, должны иметь префикс. Реализация должна генерировать для таких элементов только префикс 'db:' и может воспринимать только префикс 'db:'.

11.3. Валидация

За исключением, как отмечено в отношении адресов 'to' и 'from' для строф из пространства имен 'jabber:server', сервер не несет ответственности за валидацию XML-элементов, переадресуемых клиенту или другому серверу. Конкретная реализация может решить предоставлять только проверенные информационные элементы, но это является опционным (хотя реализация не должна воспринимать XML, которые плохо сформатированы). Клиенты не должны полагаться на возможность посылки данных, неследующих заданным формам, и должны игнорировать любые нестандартные элементы или атрибуты во входном XML-потоке. Валидация XML-потоков и строф является опционной.

11.4. Включение текстовых деклараций

Реализации должны посылать текстовые декларации до посылки заголовка потока. Приложения должны следовать правилам из [XML], в зависимости от обстоятельств, при которых включается текстовая декларация.

11.5. Кодирование символов

Реализации должны поддерживать UTF-8 (RFC 3629 [UTF-8]) преобразования универсального символьного набора (ISO/IEC 10646-1 [UCS2]), как этого требует RFC 2277 [CHARSET]. Реализации не должны пытаться использовать любые другие виды кодирования.

12. Основные требования совместимости

Этот раздел суммирует специфические аспекты протокола XMPP, которые должны поддерживаться серверами и клиентами, для того чтобы быть совместимыми. Для целей совместимости мы проводим различие между базовыми протоколами (которые должны поддерживаться любым сервером или клиентом, вне зависимости от специфичности приложений) и протокола отправки сообщений в реальном масштабе времени (IM) (которые должны поддерживаться IM и приложениями присутствия, работающими поверх базовых протоколов). Требования совместимости, которые приложимы ко всем серверам и клиентам, специфицированы ниже. Требования совместимости для IM серверов и клиентов описаны в разделе [XMPP-IM].

12.1. Серверы

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

  • Применение профайлов [NAMEPREP], Nodeprep (Приложение A) и Resourceprep (Приложение B) [STRINGPREP] к адресам (включая гарантию того, что идентификаторы доменов являются международными доменными именами, как это определено в [IDNA])
  • XML-потоки (раздел 4), включая использование TLS (раздел 5), использование SASL (раздел 6) и подключение ресурсов (раздел 7)
  • Базовая семантика трех основных видов строф (т.е., <message/>, <presence/> и <iq/>), как это определено в разделе 9
  • Генерация синтаксиса ошибок и семантик, относящаяся к потокам, TLS, SASL и XML-строфам

Кроме того сервер может поддерживать серверный dialback (раздел 8).

12.2. Клиенты

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

  • XML-потоки (раздел 4), включая использование TLS (раздел 5), использование SASL (раздел 6) и подключение ресурсов (раздел 7)
  • Базовая семаника трех определенных видов строф (т.е., <message/>, <presence/> и <iq/>), как это специфицировано в семантике строф (раздел 9)
  • Обработка (и, где возможно, генерация) синтаксиса ошибок и семантики, сопряженной с потоками, TLS, SASL и XML-строфами.

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

  • Генерация адресов, в которых профайлы [NAMEPREP], Nodeprep (Приложение A), и Resourceprep (Приложение B) [STRINGPREP] могут успешно работать

13. Соображения интернационализации

XML-потоки должны кодироваться в UTF-8, как это специфицировано в главе "Кодирование символов" (раздел 11). Согласно описанию атрибутов потока (раздел 4), XML-поток должен содержать атрибут 'xml:lang', значение которого рассматривается как язык по умолчанию для любых символьных XML-данных, пересылаемых через поток, который предназначен для восприятия человеком. Как это специфицировано в xml:lang (раздел 9), XML-строфа должна включать в себя атрибут 'xml:lang', если строфа содержит символьные XML-данные, которые предназначены пользователю-человеку. Сервер должен использовать значение атрибута 'xml:lang' по умолчанию для строф, которые он переадресовывает или доставляет одному из подключенных объектов, и не должен модифицировать или удалять атрибуты 'xml:lang' из строф, которые он получает от других объектов.

14. Соображения безопасности

14.1. Высокая безопасность

Для целей XMPP-коммуникаций (клиент-сервер и сервер-сервер), термин "Высокая безопасность" относится к использованию технологий безопасности, которые обеспечивают как взаимную аутентификацию, так и проверку целостности; в частности, когда для гарантии безопасности используется аутентификация, основанная на применении сертификатов, цепочка проверки должна использовать свои маршруты. В отношении процедуры проверки сертификатов смотри раздел 14 ниже.

Реализации должны поддерживать высокую безопасность. Предоставление услуг должно предполагать применение высокой безопасности.

14.2. Валидация сертификатов

Когда XMPP-партнер осуществляет связь с другим объектом безопасным образом, он должен проверить сертификат партнера.

Существует три возможных варианта:

  • Случай #1: Партнер имеет сертификат оконечного объекта, который оказывается сертифицирован цепочкой сертификатов (как описано в разделе 6.1 [X509]).
  • Случай #2: Сертификат партнера подтвержден центром сертификации, неизвестным проверяющему партнеру.
  • Случай #3: Сертификат партнера подписан им самим.

В случае #1, осуществляющий валидацию партнер должен выполнить одну из двух вещей:

  1. Верифицировать сертификат партнера согласно правилам [X509]. Сертификат должен быть затем проверен на предмет ожидаемой идентичности партнера согласно правил из [HTTP-TLS], за исключением того, что для идентификации партнера должно использоваться расширение subjectAltName типа "xmpp" (если имеется). Если одна из этих проверок не прошла, клиенты, ориентированные на пользователя, должны либо уведомить пользователя (клиенты в любом случае могут дать возможность пользователю сохранить соединение) или разорвать соединение с "неисправимой ошибкой сертификата". Автоматические клиенты должны разорвать соединение и сделать запись в соответствующий журнальный файл. Автоматические клиенты могут предоставить конфигурационные установки, которые блокируют эту проверку, но должны предоставить возможность ее восстановления.

  2. Партнер должен предъявить сертификат пользователю для одобрения, включая всю сертификационную цепочку. Партнер должен кэшировать сертификат (или некоторую неподделываемую презентацию сертификата типа хэша). При будущих соединениях партнер должен верифицировать факт идентичности предъявляемого сертификата и уведомлять пользователя, если он изменился.

В случае #2 и #3, реализации должны действовать как в (2) выше.

14.3. Коммуникации клиент-сервер

Совместимые клиентские реализации должны поддерживать для подключения сервера как TLS, так и SASL.

Протокол TLS для криптографического преобразования XML-потоков (определенного в рамках использования TLS (раздел 5)) предоставляет надежный механизм гарантирования конфиденциальности и целостности данных, пересылаемых между двумя объектами.

Протокол SASL для аутентификации XML-потоков (определено в главе "Использование SASL" (раздел 6)) предоставляет надежный механизм валидации того, что клиент, подключенный к серверу, является тем, за кого он себя выдает.

Коммуникации клиент-сервер не должны осуществляться, до тех пор пока имя машины, представленное сервером не будет выявлено. Такие процедуры сначала должны пытаться выяснить имя машины, используя сервис [SRV] "xmpp-client" и протокол "tcp", получая в результате рекорды типа "_xmpp-client._tcp.example.com." (использование строки "xmpp-client" для идентификатора сервиса согласуется с регламентациями IANA). Если SRV lookup терпит неудачу, методом решения проблемы будет выявление IPv4/IPv6-адресов, используя "xmpp-client" порт 5222, стандартизованный IANA.

IP-адрес и метод доступа к клиенту не должны делаться сервером публично доступными. Это помогает защитить сервер клиента от прямой атаки.

14.4. Коммуникации сервер-сервер

Совместимые реализации сервера должны для междоменных коммуникаций поддерживать как TLS, так и SASL. По историческим причинам, совместимые реализации сервера должны поддерживать Dialback (раздел 8).

Так как предоставление услуг является вопросом политики, коммуникации с другими доменами являются опционным для любого выбранного домена, и коммуникации сервер-сервер могут быть запрещены администратором. Если конкретному домену разрешены междоменные коммуникации, он должен обеспечивать высокий уровень безопасности.

Администраторы могут потребовать для коммуникаций сервер-сервер использования SASL, для того чтобы гарантировать как аутентификацию, так и конфиденциальность. По этой причине совместимые реализации должны поддерживать SASL.

Междоменные соединения не должны функционировать до тех пор, пока имена машин, предоставленные сервером, не были идентифицированы. Такая процедура для получения ресурсных записей "_xmpp-server._tcp.example.com." должна сначала воспользоваться сервисом "xmpp-server" [SRV] и протоколом "tcp" (использование строки "xmpp-server" для идентификатора сервиса согласуется с требованиями IANA.

Заметим, что идентификатор "xmpp-server" заменил ранее использовавшийся "jabber". Если процедура SRV lookup терпит неудачу, следует выяснить традиционный IPv4/IPv6 адрес, используя "xmpp-server" порт 5269, зарегистрированный IANA.

Серверный dialback помогает защититься от фальсификации домена, делая более трудным фальсификацию XML-строф. Это не механизм аутентификации, обеспечения безопасности или шифрования строф между серверами, как это делается с помощью SASL и TLS. Процедура предлагает лишь слабую верификацию идентичности сервера. Кроме того, эта процедура уязвима для атак фальсификации DNS, если только не используется DNSSec [DNSSEC], и даже если информация DNS корректна, dialback не может защитить от атак, в которых атакер может украсть IP-адрес удаленного домена. Домены, требующие надежной безопасности должны использовать TLS и SASL. Если для аутентификации сервер-сервер используется SASL, dialback не следует использовать в силу полной бесполезности.

14.5. Порядок слоев

Порядок протокольных слоев в стеке должен быть следующим:

  1. TCP
  2. TLS
  3. SASL
  4. XMPP

Разумность такого порядка заключается в том, что он является основой [TCP] упорядочения для всего стека протоколов, работающих поверх TCP.

14.6. Необходимость SASL для подключения канала к TLS

Система SASL не предоставляет механизма подключения аутентификации SASL к уровню безопасности обеспечивающему конфиденциальность и целостность, которые согласованы на более низком уровне. Этот недостаток канальной привязки мешает SASL верифицировать, являются ли конечные точки виртуального канала, сформированного нижним уровнем безопасности, конечными точками, которые аутентифицировала SASL. Если конечные точки не идентичны, нижнему уровню безопасности нельзя доверять защиту данных, передаваемых между объектами SASL. В такой ситуации нужно согласовывать уровень безопасности SASL, который эффективно игнорирует более низкий уровень безопасности.

14.7. Обязательные для использования технологии

По минимуму все реализации должны поддерживать следующие механизмы:

  • для аутентификации: механизм SASL [DIGEST-MD5]

  • для конфиденциальности: TLS (используя шифр TLS_RSA_WITH_3DES_EDE_CBC_SHA)

  • для обих: TLS плюс SASL EXTERNAL(используя TLS_RSA_WITH_3DES_EDE_CBC_SHA шифр, поддерживающий сертификаты стороны клиента)

14.8. Firewalls

Коммуникации, использующие XMPP, в норме происходят поверх соединения через порт 5222 [TCP] (клиент-сервер) или порт 5269 (сервер-сервер), как это зарегистрировано IANA (смотри "Соображения IANA" (раздел 15)). Использование этих стандартных портов позволяет администраторам легко разрешить или запретить XMPP, делается это с помощью существующих стандартных firewall.

14.9. Использование кодирования base64 в SASL

Как клиент так и сервер должны верифицировать любые данные [BASE64], полученные в ходе согласования SASL. Реализация должна отвергать (или игнорировать) любые символы, которые неявно разрешены в кодировке base64. Это помогает защититься от создания скрытого канала, который может использоваться для "утечки" информации. Реализация не должна разрывать соединение при некорректном вводе, она должна отвергать любую последовательность символов base64, содержащую символ ('='), если такой символ включен не в качестве последнего символа данных (например, "=AAA" или "BBBB=CCC"). Это помогает защититься от атак переполнения буфера и некоторых других атак. Кодировка base64 визуально скрывает легко узнаваемую текстовую информацию, такую как пароли, но не обеспечивает конфиденциальности. Кодировка base64 должна следовать определениям из раздела 3 RFC 3548 [BASE64].

14.10. Профайлы Stringprep

XMPP использует профайл [NAMEPREP] из [STRINGPREP] для обработки идентификаторов доменов. Соображения безопасности, относящиеся к Nameprep, рассмотрены в соответствующем разделе [NAMEPREP].

Кроме того, XMPP определяет два профайла [STRINGPREP]: Nodeprep (Приложение A) для идентификаторов узлов и Resourceprep (Приложение B) для идентификаторов ресурсов.

В символьных наборах Unicode и ISO/IEC 10646 имеется много символов, которые выглядят сходным образом. Во многих случаях, пользователи протоколов безопасности могут осуществить визуальное распознавание имен объектов. Так как невозможно установить соответствие для символов идентичного вида без учета контекста (например, знания того, какой шрифт использован) stringprep не делает ничего для установления соответствия между идентично выглядящими символами и не запрещает использования таких символов.

Идентификатор узла может использоваться в качестве части адреса объекта в XMPP. Безопасность таких сервисов может быть скомпрометирована с помощью различной интерпретации интернациализированных идентификаторов узлов. Например, пользователь, вводящий один интернационализированный идентификатор может получить доступ к информации аккоунта другого пользователя.

Идентификатор ресурса может использоваться как часть адреса объекта в XMPP. Одним общим применением является имя пользователя при IM (активная сессия); другим может быть прозвище пользователя при многопользовательской сессии. Безопасность таких сервисов может быть скомпрометирована с помощью разной интерпретации интернациализированных идентификаторов узлов. например, пользователь может попытаться инициировать несколько сессий под одним и тем же именем, или пользователь может послать сообщение кому-то отличному от зарегистрированного получателя многопользовательской сессии.

15. Соображения IANA

15.1. Имя XML-пространства имен для данных TLS

Субпространство имен URN для данных, связанных с TLS, в XMPP определено следующим образом. Это пространство имен сопряжено с форматом, определенным в IETF XML Registry [XML-REG].

URI: urn:ietf:params:xml:ns:xmpp-tls
Specification: RFC 3920
Description: This is the XML namespace name for TLS-related data in
   the Extensible Messaging and Presence Protocol (XMPP) as defined
   by RFC 3920.
Registrant Contact: IETF, XMPP Working Group, <[email protected]
>

15.2. Имя XML-пространства имен для данных SASL

Субпространство имен URN для данных, связанных с SASL, в XMPP определено следующим образом. Это пространство имен сопряжено с форматом, определенным в [XML-REG].

URI: urn:ietf:params:xml:ns:xmpp-sasl
Specification: RFC 3920
Description: This is the XML namespace name for SASL-related data in
   the Extensible Messaging and Presence Protocol (XMPP) as defined
   by RFC 3920.
Registrant Contact: IETF, XMPP Working Group, <[email protected]
>

15.3. Имя XML-пространства имен для ошибок потока

Субпространство имен URN для данных, связанных ошибками потоков в XMPP определено следующим образом. Это пространство имен сопряжено с форматом, определенным в [XML-REG].

URI: urn:ietf:params:xml:ns:xmpp-streams
Specification: RFC 3920
Description: This is the XML namespace name for stream-related error
   data in the Extensible Messaging and Presence Protocol (XMPP) as
   defined by RFC 3920.
Registrant Contact: IETF, XMPP Working Group, <[email protected]
>

15.4. Имя XML-пространства имен для подключения ресурсов

Субпространство имен URN для подключения ресурсов в XMPP (Extensible Messaging and Presence Protocol) определяется следующим образом. Это имя пространства имен соответствует формату, определенному в [XML-REG].

URI: urn:ietf:params:xml:ns:xmpp-bind
Specification: RFC 3920
Description: This is the XML namespace name for resource binding in
   the Extensible Messaging and Presence Protocol (XMPP) as defined
   by RFC 3920.
Registrant Contact: IETF, XMPP Working Group, <[email protected]
>

15.5. Имя XML-пространства имен для ошибок строф

Субпространство имен URN для данных, связанных с ошибками строф в XMPP определено следующим образом. Это имя пространства имен соответствует формату, определенному в [XML-REG].

URI: urn:ietf:params:xml:ns:xmpp-stanzas
Specification: RFC 3920
Description: This is the XML namespace name for stanza-related error
   data in the Extensible Messaging and Presence Protocol (XMPP) as
   defined by RFC 3920.
Registrant Contact: IETF, XMPP Working Group, <[email protected]
>

15.6. Nodeprep-профайл Stringprep

Профайл Nodeprep для stringprep определен в рамках Nodeprep (Приложение A). IANA зарегистрировала Nodeprep в регистре профайлов stringprep.

  • Имя этого профайла:

  • Nodeprep

  • RFC, в котором описан профайл:

  • RFC 3920

15.7. Профайл Resourceprep из Stringprep

Профайл Resourceprep из stringprep определен в рамках Resourceprep (Приложение B). IANA зарегистрировала Resourceprep в регистре профайлов stringprep.

  • Имя этого профайла:

  • Resourceprep

  • RFC, в котором описан профайл:

  • RFC 3920

15.8. Имя сервиса GSSAPI

IANA зарегистрировала "xmpp" в качестве имени сервиса GSSAPI [GSS-API], как это задано в рамках определения SASL (раздел 6).

15.9. Номера портов

IANA зарегистрировала ключевые слова xmpp-client и xmpp-server для обозначения номеров портов для ТСР-обмена 5222 и 5269, соответственно. Эти номера портов следует использовать для обменов клиент-сервер и сервер-клиент.

16. Литература

16.1. Нормативные документы

[ABNF] Crocker, D. и P. Overell, «Augmented BNF for Syntax Specifications: ABNF», RFC 2234, Ноябрь 1997.
[BASE64] Josefsson, S., «The Base16, Base32, and Base64 Data Encodings», RFC 3548, Июль 2003.
[CHARSET] Alvestrand, H., «IETF Policy on Character Sets and Languages», BCP 18, RFC 2277, Январь 1998.
[DIGEST-MD5] Leach, P. и C. Newman, «Using Digest Authentication as a SASL Mechanism», RFC 2831, Май 2000.
[DNS] Mockapetris, P., «Domain names — implementation and specification», STD 13, RFC 1035, Ноябрь 1987.
[GSS-API] Linn, J., «Generic Security Service Application Program Interface Version 2, Update 1», RFC 2743, Январь 2000.
[HTTP-TLS] Rescorla, E., «HTTP Over TLS», RFC 2818, Май 2000.
[IDNA] Faltstrom, P., Hoffman, P., and A. Costello, «Internationalizing Domain Names in Applications (IDNA)», RFC 3490, Март 2003.
[IPv6] Hinden, R. и S. Deering, «Internet Protocol Version 6 (IPv6) Addressing Architecture», RFC 3513, Апрель 2003.
[LANGTAGS] Alvestrand, H., «Tags for the Identification of Languages», BCP 47, RFC 3066, Январь 2001.
[NAMEPREP] Hoffman, P. и M. Blanchet, «Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)», RFC 3491, Март 2003.
[RANDOM] Eastlake 3rd, D., Crocker, S., and J. Schiller, «Randomness Recommendations for Security», RFC 1750, Декабрь 1994.
[SASL] Myers, J., «Simple Authentication and Security Layer (SASL)», RFC 2222, October 1997.
[SRV] Gulbrandsen, A., Vixie, P., and L. Esibov, «A DNS RR for specifying the location of services (DNS SRV)», RFC 2782, Февраль 2000.
[STRINGPREP] Hoffman, P. и M. Blanchet, «Preparation of Internationalized Strings ("stringprep")», RFC 3454, Декабрь 2002.
[TCP] Postel, J., «Протокол управления передачей (TCP)», STD 7, RFC 793, Сентябрь 1981.
[TERMS] Bradner, S., «Key words for use in RFCs to Indicate Requirement Levels», BCP 14, RFC 2119, Март 1997.
[TLS] Dierks, T. и C. Allen, «Протокол TLS 1.0», RFC 2246, Январь 1999
[UCS2] International Organization for Standardization, «Information Technology — Universal Multiple-octet coded Character Set (UCS) — Amendment 2: UCS Transformation Format 8 (UTF-8)», ISO Standard 10646-1 Addendum 2, October 1996.
[UTF-8] Yergeau, F., «UTF-8, a transformation format of ISO 10646», STD 63, RFC 3629, Ноябрь 2003.
[X509] Housley, R., Polk, W., Ford, W., and D. Solo, «Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile», RFC 3280, Апрель 2002.
[XML] Bray, T., Paoli, J., Sperberg-McQueen, C., and E. Maler, «Extensible Markup Language (XML) 1.0 (2nd ed)», W3C REC-xml, Октябрь 2000.
[XML-NAMES] Bray, T., Hollander, D., and A. Layman, «Namespaces in XML», W3C REC-xml-names, Январь 1999.

16.2. Дополнительная литература

[ACAP] Newman, C. и J. Myers, «ACAP — Application Configuration Access Protocol», RFC 2244, Ноябрь 1997.
[ASN.1] CCITT, «Recommendation X.208: Specification of Abstract Syntax Notation One (ASN.1)», 1988.
[DNSSEC] Eastlake 3rd, D., «Domain Name System Security Extensions», RFC 2535, Март 1999.
[HTTP] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, «Hypertext Transfer Protocol — HTTP/1.1», RFC 2616, Июнь 1999.
[IMAP] Crispin, M., «INTERNET MESSAGE ACCESS PROTOCOL — VERSION 4rev1», RFC 3501, Март 2003.
[IMP-REQS] Day, M., Aggarwal, S., Mohr, G., and J. Vincent, «Instant Messaging / Presence Protocol Requirements», RFC 2779, Февраль 2000.
[IRC] Oikarinen, J. и D. Reed, «Протокол IRC», RFC 1459, Май 1993.
[JEP-0029] Kaes, C., «Definition of Jabber Identifiers (JIDs)», JSF JEP 0029, Октябрь 2003.
[JEP-0078] Saint-Andre, P., «Non-SASL Authentication», JSF JEP 0078, Июль 2004.
[JEP-0086] Norris, R. и P. Saint-Andre, «Error Condition Mappings», JSF JEP 0086, Февраль 2004.
[JSF] Jabber Software Foundation, «Jabber Software Foundation».
[POP3] Myers, J. и M. Rose, «Протокол POP3», STD 53, RFC 1939, Май 1996.
[SIMPLE] SIMPLE Working Group, «SIMPLE WG».
[SMTP] Klensin, J., «Simple Mail Transfer Protocol», RFC 2821, Апрель 2001.
[URI] Berners-Lee, T., Fielding, R., and L. Masinter, «Uniform Resource Identifiers (URI): Generic Syntax», RFC 2396, Август 1998.
[USINGTLS] Newman, C., «Using TLS with IMAP, POP3 and ACAP», RFC 2595, Июнь 1999.
[XML-REG] Mealling, M., «The IETF XML Registry», BCP 81, RFC 3688, Январь 2004.
[XMPP-IM] Saint-Andre, P., Ed., «Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence», RFC 3921, Октябрь 2004.

Приложение A. Nodeprep

A.1. Введение

Это приложение определяет профайл "Nodeprep" из [NAMEPREP]. Как таковой, он специфицирует правила обработки, которые позволят пользователям вводить интернационализированные идентификаторы узлов в XMPP и иметь при этом содержимое строк корректным. Идентификатор узла XMPP является опционной частью XMPP-адреса, которая предшествует идентификатору домена и сепаратору '@'. Он часто но не всегда ассоциируется именем пользователя при IM. Эти правила обработки ориентированы только на XMPP идентификаторы узлов, а не для произвольных текстов или любых аспектов XMPP-адреса.

Этот профайл определяет следующее, как это определено в [NAMEPREP]:

  • Профайл предназначен для: интернациализированных идентификаторов узлов в рамках XMPP
  • Символьный репертуар, который является входными и выходными данными для stringprep: Unicode 3.2 специфицирован в разделе 2 этого приложения
  • Используемые соответствия (mapping): специфицированы в разделе 3
  • Используемая нормализация Unicode: специфицирована в разделе 4
  • Символы, которые запрещены для выхода: специфицированы в разделе 5
  • Реверсивная обработка символов: специфицирована в разделе 6

A.2. Репертуар символов

Этот профайл использует Unicode 3.2 со списком неприсвоенных кодовых значений таблицы A.1, определенной в Приложение A [NAMEPREP].

A.3. Соответствие

Этот профайл специфицирует соответствие при использовании таблиц из [STRINGPREP]:

  • Table B.1
  • Table B.2

A.4. Нормализация

Этот профайл специфицирует использование Unicode формы нормализации KC, как это описано в [NAMEPREP].

A.5. Запрещенный вывод

Этот профайл специфицирует запрет использования следующих таблиц из [NAMEPREP].

  • Table C.1.1
  • Table C.1.2
  • Table C.2.1
  • Table C.2.2
  • Table C.3
  • Table C.4
  • Table C.5
  • Table C.6
  • Table C.7
  • Table C.8
  • Table C.9

Кроме того, запрещены также следующие Unicode-символы:

  • #x22 (")
  • #x26 (&)
  • #x27 (')
  • #x2F (/)
  • #x3A (:)
  • #x3C (<)
  • #x3E (>)
  • #x40 (@)

A.6. Реверсивные символы

Этот профайл специфицирует проверку реверсивных строк, как это описано в разделе 6 [NAMEPREP].

Приложение B. Resourceprep

B.1. Введение

Это приложение определяет профайл "Resourceprep" [NAMEPREP]. В этом качестве оно специфицирует правила обработки, которые позволят пользователю вводить интернационализированные идентификаторы ресурсов в XMPP и иметь высокий шанс получить содержимое строк корректным. (Идентификатор ресурса XMPP является опционной частью XMPP-адреса, которая следует за доменным идентификатором и сепаратором '/'. Он часто но не всегда является ассоциированным с именем сессии IM. Эти правила обработки предназначены для идентификаторов ресурсов XMPP и не ориентированы на работу с произвольными текстами или любыми другими аспектами XMPP-адреса.

Этот профайл определяет следующее (как это требуется [STRINGPREP]):

  • Профайл предназначен для: интернацианализированных идентификаторов ресурсов в XMPP
  • Символьный репертуар, который является входом и выходом stringprep: Unicode 3.2, специфицирован в разделе 2 этого приложения
  • Используемое соответствие символов специфицировано в разделе 3
  • Используемая нормализация Unicode специфицирована в разделе 4
  • Символы, которые запрещено использовать специфицированы в разделе 5
  • Реверсивная обработка символов специфицирована в разделе 6

B.2. Символьный репертуар

Этот профайл использует Unicode 3.2 со списком неприсвоенных кодов из таблицы A.1, см. Приложение A [STRINGPREP].

B.3. Соответствие

Этот профайл специфицирует соответствие (mapping), использующее таблицу B.1 из [NAMEPREP]:

B.4. Нормализация

Этот профайл специфицирует использование формы KC нормализации Unicode, как это описано в [NAMEPREP].

B.5. Запрещенный вывод

Этот профайл специфицирует запрещенные для использования таблицы из [NAMEPREP].

  • Table C.1.2
  • Table C.2.1
  • Table C.2.2
  • Table C.3
  • Table C.4
  • Table C.5
  • Table C.6
  • Table C.7
  • Table C.8
  • Table C.9

B.6. Реверсивные символы

Этот профайл специфицирует проверку реверсивных строк, как это описано в разделе 6 [STRINGPREP].

Приложение C. XML-схемы

Следующие схемы XML являются описательными, а не нормативными. Для схем, определяющих пространства имен 'jabber:client' 'jabber:server', смотри [XMPP-IM].

C.1. Пространство имен потоков

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://etherx.jabber.org/streams'
    xmlns='http://etherx.jabber.org/streams'
    elementFormDefault='unqualified'>
  <xs:element name='stream'>
    <xs:complexType>
      <xs:sequence xmlns:client='jabber:client'
                   xmlns:server='jabber:server'
                   xmlns:db='jabber:server:dialback'>
        <xs:element ref='features' minOccurs='0' maxOccurs='1'/>
        <xs:any namespace='urn:ietf:params:xml:ns:xmpp-tls'
                minOccurs='0'
                maxOccurs='unbounded'/>
        <xs:any namespace='urn:ietf:params:xml:ns:xmpp-sasl'
                minOccurs='0'
                maxOccurs='unbounded'/>
        <xs:choice minOccurs='0' maxOccurs='1'>
          <xs:choice minOccurs='0' maxOccurs='unbounded'>
            <xs:element ref='client:message'/>
            <xs:element ref='client:presence'/>
            <xs:element ref='client:iq'/>
          </xs:choice>
          <xs:choice minOccurs='0' maxOccurs='unbounded'>
            <xs:element ref='server:message'/>
            <xs:element ref='server:presence'/>
            <xs:element ref='server:iq'/>
            <xs:element ref='db:result'/>
            <xs:element ref='db:verify'/>
          </xs:choice>
        </xs:choice>
        <xs:element ref='error' minOccurs='0' maxOccurs='1'/>
      </xs:sequence>
      <xs:attribute name='from' type='xs:string' use='optional'/>
      <xs:attribute name='id' type='xs:NMTOKEN' use='optional'/>
      <xs:attribute name='to' type='xs:string' use='optional'/>
      <xs:attribute name='version' type='xs:decimal' use='optional'/>
      <xs:attribute ref='xml:lang' use='optional'/>
    </xs:complexType>
  </xs:element>
  <xs:element name='features'>
    <xs:complexType>
      <xs:all xmlns:tls='urn:ietf:params:xml:ns:xmpp-tls'
              xmlns:sasl='urn:ietf:params:xml:ns:xmpp-sasl'
              xmlns:bind='urn:ietf:params:xml:ns:xmpp-bind'
              xmlns:sess='urn:ietf:params:xml:ns:xmpp-session'>
        <xs:element ref='tls:starttls' minOccurs='0'/>
        <xs:element ref='sasl:mechanisms' minOccurs='0'/>
        <xs:element ref='bind:bind' minOccurs='0'/>
        <xs:element ref='sess:session' minOccurs='0'/>
      </xs:all>
    </xs:complexType>
  </xs:element>
  <xs:element name='error'>
    <xs:complexType>
      <xs:sequence  xmlns:err='urn:ietf:params:xml:ns:xmpp-streams'>
        <xs:group   ref='err:streamErrorGroup'/>
        <xs:element ref='err:text'
                    minOccurs='0'
                    maxOccurs='1'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

C.2. Пространство имен потоковых ошибок

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='urn:ietf:params:xml:ns:xmpp-streams'
    xmlns='urn:ietf:params:xml:ns:xmpp-streams'
    elementFormDefault='qualified'>
  <xs:element name='bad-format' type='empty'/>
  <xs:element name='bad-namespace-prefix' type='empty'/>
  <xs:element name='conflict' type='empty'/>
  <xs:element name='connection-timeout' type='empty'/>
  <xs:element name='host-gone' type='empty'/>
  <xs:element name='host-unknown' type='empty'/>
  <xs:element name='improper-addressing' type='empty'/>
  <xs:element name='internal-server-error' type='empty'/>
  <xs:element name='invalid-from' type='empty'/>
  <xs:element name='invalid-id' type='empty'/>
  <xs:element name='invalid-namespace' type='empty'/>
  <xs:element name='invalid-xml' type='empty'/>
  <xs:element name='not-authorized' type='empty'/>
  <xs:element name='policy-violation' type='empty'/>
  <xs:element name='remote-connection-failed' type='empty'/>
  <xs:element name='resource-constraint' type='empty'/>
  <xs:element name='restricted-xml' type='empty'/>
  <xs:element name='see-other-host' type='xs:string'/>
  <xs:element name='system-shutdown' type='empty'/>
  <xs:element name='undefined-condition' type='empty'/>
  <xs:element name='unsupported-encoding' type='empty'/>
  <xs:element name='unsupported-stanza-type' type='empty'/>
  <xs:element name='unsupported-version' type='empty'/>
  <xs:element name='xml-not-well-formed' type='empty'/>
  <xs:group name='streamErrorGroup'>
    <xs:choice>
      <xs:element ref='bad-format'/>
      <xs:element ref='bad-namespace-prefix'/>
      <xs:element ref='conflict'/>
      <xs:element ref='connection-timeout'/>
      <xs:element ref='host-gone'/>
      <xs:element ref='host-unknown'/>
      <xs:element ref='improper-addressing'/>
      <xs:element ref='internal-server-error'/>
      <xs:element ref='invalid-from'/>
      <xs:element ref='invalid-id'/>
      <xs:element ref='invalid-namespace'/>
      <xs:element ref='invalid-xml'/>
      <xs:element ref='not-authorized'/>
      <xs:element ref='policy-violation'/>
      <xs:element ref='remote-connection-failed'/>
      <xs:element ref='resource-constraint'/>
      <xs:element ref='restricted-xml'/>
      <xs:element ref='see-other-host'/>
      <xs:element ref='system-shutdown'/>
      <xs:element ref='undefined-condition'/>
      <xs:element ref='unsupported-encoding'/>
      <xs:element ref='unsupported-stanza-type'/>
      <xs:element ref='unsupported-version'/>
      <xs:element ref='xml-not-well-formed'/>
    </xs:choice>
  </xs:group>
  <xs:element name='text'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='xs:string'>
          <xs:attribute ref='xml:lang' use='optional'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

C.3. Пространство имен TLS

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='urn:ietf:params:xml:ns:xmpp-tls'
    xmlns='urn:ietf:params:xml:ns:xmpp-tls'
    elementFormDefault='qualified'>
  <xs:element name='starttls'>
    <xs:complexType>
      <xs:sequence>
        <xs:element
            name='required'
            minOccurs='0'
            maxOccurs='1'
            type='empty'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name='proceed' type='empty'/>
  <xs:element name='failure' type='empty'/>
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

C.4. Пространство имен SASL

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='urn:ietf:params:xml:ns:xmpp-sasl'
    xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
    elementFormDefault='qualified'>
  <xs:element name='mechanisms'>
    <xs:complexType>
      <xs:sequence>
        <xs:element name='mechanism'
                    maxOccurs='unbounded'
                    type='xs:string'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name='auth'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='mechanism'
                        type='xs:string'
                        use='optional'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  <xs:element name='challenge' type='xs:string'/>
  <xs:element name='response' type='xs:string'/>
  <xs:element name='abort' type='empty'/>
  <xs:element name='success' type='empty'/>
  <xs:element name='failure'>
    <xs:complexType>
      <xs:choice minOccurs='0'>
        <xs:element name='aborted' type='empty'/>
        <xs:element name='incorrect-encoding' type='empty'/>
        <xs:element name='invalid-authzid' type='empty'/>
        <xs:element name='invalid-mechanism' type='empty'/>
        <xs:element name='mechanism-too-weak' type='empty'/>
        <xs:element name='not-authorized' type='empty'/>
        <xs:element name='temporary-auth-failure' type='empty'/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

C.5. Пространство имен подключения ресурсов

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='urn:ietf:params:xml:ns:xmpp-bind'
    xmlns='urn:ietf:params:xml:ns:xmpp-bind'
    elementFormDefault='qualified'>
  <xs:element name='bind'>
    <xs:complexType>
      <xs:choice minOccurs='0' maxOccurs='1'>
        <xs:element name='resource' type='xs:string'/>
        <xs:element name='jid' type='xs:string'/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

C.6. Пространство имен Dialback

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='jabber:server:dialback'
    xmlns='jabber:server:dialback'
    elementFormDefault='qualified'>
  <xs:element name='result'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='xs:token'>
          <xs:attribute name='from' type='xs:string' use='required'/>
          <xs:attribute name='to' type='xs:string' use='required'/>
          <xs:attribute name='type' use='optional'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='invalid'/>
                <xs:enumeration value='valid'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  <xs:element name='verify'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='xs:token'>
          <xs:attribute name='from' type='xs:string' use='required'/>
          <xs:attribute name='id' type='xs:NMTOKEN' use='required'/>
          <xs:attribute name='to' type='xs:string' use='required'/>
          <xs:attribute name='type' use='optional'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='invalid'/>
                <xs:enumeration value='valid'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
</xs:schema>

C.7. Пространство имен ошибок строф

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='urn:ietf:params:xml:ns:xmpp-stanzas'
    xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'
    elementFormDefault='qualified'>
  <xs:element name='bad-request' type='empty'/>
  <xs:element name='conflict' type='empty'/>
  <xs:element name='feature-not-implemented' type='empty'/>
  <xs:element name='forbidden' type='empty'/>
  <xs:element name='gone' type='xs:string'/>
  <xs:element name='internal-server-error' type='empty'/>
  <xs:element name='item-not-found' type='empty'/>
  <xs:element name='jid-malformed' type='empty'/>
  <xs:element name='not-acceptable' type='empty'/>
  <xs:element name='not-allowed' type='empty'/>
  <xs:element name='payment-required' type='empty'/>
  <xs:element name='recipient-unavailable' type='empty'/>
  <xs:element name='redirect' type='xs:string'/>
  <xs:element name='registration-required' type='empty'/>
  <xs:element name='remote-server-not-found' type='empty'/>
  <xs:element name='remote-server-timeout' type='empty'/>
  <xs:element name='resource-constraint' type='empty'/>
  <xs:element name='service-unavailable' type='empty'/>
  <xs:element name='subscription-required' type='empty'/>
  <xs:element name='undefined-condition' type='empty'/>
  <xs:element name='unexpected-request' type='empty'/>
  <xs:group name='stanzaErrorGroup'>
    <xs:choice>
      <xs:element ref='bad-request'/>
      <xs:element ref='conflict'/>
      <xs:element ref='feature-not-implemented'/>
      <xs:element ref='forbidden'/>
      <xs:element ref='gone'/>
      <xs:element ref='internal-server-error'/>
      <xs:element ref='item-not-found'/>
      <xs:element ref='jid-malformed'/>
      <xs:element ref='not-acceptable'/>
      <xs:element ref='not-allowed'/>
      <xs:element ref='payment-required'/>
      <xs:element ref='recipient-unavailable'/>
      <xs:element ref='redirect'/>
      <xs:element ref='registration-required'/>
      <xs:element ref='remote-server-not-found'/>
      <xs:element ref='remote-server-timeout'/>
      <xs:element ref='resource-constraint'/>
      <xs:element ref='service-unavailable'/>
      <xs:element ref='subscription-required'/>
      <xs:element ref='undefined-condition'/>
      <xs:element ref='unexpected-request'/>
    </xs:choice>
  </xs:group>
  <xs:element name='text'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='xs:string'>
          <xs:attribute ref='xml:lang' use='optional'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

Appendix D. Differences Between Core Jabber Protocols and XMPP

This section is non-normative.

XMPP has been adapted from the protocols originally developed in the Jabber open-source community, which can be thought of as "XMPP 0.9". Because there exists a large installed base of Jabber implementations and deployments, it may be helpful to specify the key differences between the relevant Jabber protocols and XMPP in order to expedite and encourage upgrades of those implementations and deployments to XMPP. This section summarizes the core differences, while the corresponding section of [XMPP-IM] summarizes the differences that relate specifically to instant messaging and presence applications.

D.1. Channel Encryption

It was common practice in the Jabber community to use SSL for channel encryption on ports other than 5222 and 5269 (the convention is to use ports 5223 and 5270). XMPP uses TLS over the IANA-registered ports for channel encryption, as defined under Use of TLS (Section 5) herein.

D.2. Authentication

The client-server authentication protocol developed in the Jabber community used a basic IQ interaction qualified by the 'jabber:iq:auth' namespace (documentation of this protocol is contained in [JEP-0078], published by the Jabber Software Foundation [JSF]). XMPP uses SASL for authentication, as defined under Use of SASL (Section 6) herein.

The Jabber community did not develop an authentication protocol for server-to-server communications, only the Server Dialback (Section 8) protocol to prevent server spoofing. XMPP supersedes Server Dialback with a true server-to-server authentication protocol, as defined under Use of SASL (Section 6) herein.

D.3. Resource Binding

Resource binding in the Jabber community was handled via the 'jabber:iq:auth' namespace (which was also used for client authentication with a server). XMPP defines a dedicated namespace for resource binding as well as the ability for a server to generate a resource identifier on behalf of a client, as defined under Resource Binding (Section 7).

D.4. JID Processing

JID processing was somewhat loosely defined by the Jabber community (documentation of forbidden characters and case handling is contained in [JEP-0029], published by the Jabber Software Foundation [JSF]). XMPP specifies the use of [NAMEPREP] for domain identifiers and supplements Nameprep with two additional [STRINGPREP] profiles for JID processing: Nodeprep (Appendix A) for node identifiers and Resourceprep (Appendix B) for resource identifiers.

D.5. Error Handling

Stream-related errors were handled in the Jabber community via XML character data text in a <stream:error/> element. In XMPP, stream-related errors are handled via an extensible mechanism defined under Stream Errors (Section 4.7) herein.

Stanza-related errors were handled in the Jabber community via HTTP-style error codes. In XMPP, stanza-related errors are handled via an extensible mechanism defined under Stanza Errors (Section 9.3) herein. (Documentation of a mapping between Jabber and XMPP error handling mechanisms is contained in [JEP-0086], published by the Jabber Software Foundation [JSF].)

D.6. Internationalization

Although use of UTF-8 has always been standard practice within the Jabber community, the community did not define mechanisms for specifying the language of human-readable text provided in XML character data. XMPP specifies the use of the 'xml:lang' attribute in such contexts, as defined under Stream Attributes (Section 4.4) and xml:lang (Section 9.1.5) herein.

D.7. Stream Version Attribute

The Jabber community did not include a 'version' attribute in stream headers. XMPP specifies inclusion of that attribute as a way to signal support for the stream features (authentication, encryption, etc.) defined under Version Support (Section 4.4.1) herein.

Авторы

Most of the core aspects of the Extensible Messaging and Presence Protocol were developed originally within the Jabber open-source community in 1999. This community was founded by Jeremie Miller, who released source code for the initial version of the jabber server in January 1999. Major early contributors to the base protocol also included Ryan Eatmon, Peter Millard, Thomas Muldowney, and Dave Smith. Work by the XMPP Working Group has concentrated especially on security and internationalization; in these areas, protocols for the use of TLS and SASL were originally contributed by Rob Norris, and stringprep profiles were originally contributed by Joe Hildebrand. The error code syntax was suggested by Lisa Dusseault.

Благодарности

Thanks are due to a number of individuals in addition to the contributors listed. Although it is difficult to provide a complete list, the following individuals were particularly helpful in defining the protocols or in commenting on the specifications in this memo: Thomas Charron, Richard Dobson, Sam Hartman, Schuyler Heath, Jonathan Hogg, Cullen Jennings, Craig Kaes, Jacek Konieczny, Alexey Melnikov, Keith Minkler, Julian Missig, Pete Resnick, Marshall Rose, Alexey Shchepin, Jean-Louis Seguineau, Iain Shigeoka, Greg Troxel, and David Waite. Thanks also to members of the XMPP Working Group and the IETF community for comments and feedback provided throughout the life of this memo.

Адрес автора

Peter Saint-Andre (editor)
Jabber Software Foundation
EMail: gro.rebbaj@retepts

2007 - 2022 © Русские переводы RFC, IETF, ISOC.