Merge remote-tracking branch 'xsf/master'

This commit is contained in:
Simon Tennant 2015-11-13 17:24:42 +01:00
commit 0a5bb4f915
45 changed files with 4696 additions and 713 deletions

83
Makefile Normal file
View File

@ -0,0 +1,83 @@
.SILENT:
OUTDIR?=build
RESOURCESDIR=$(OUTDIR)/resources
TEMPDIR?=$(OUTDIR)/xepbuild
XMLDEPS=xep.xsl xep.xsd xep.ent xep.dtd ref.xsl $(OUTDIR)
TEXMLDEPS=xep2texml.xsl $(TEMPDIR) $(XMLDEPS) $(RESOURCESDIR)/xmpp.pdf $(RESOURCESDIR)/xmpp-text.pdf
XMPPIMAGESURL=https://xmpp.org/images
XEPDIRS=. inbox
.PHONY: help
help:
@echo 'XEP makefile targets:'
@echo ' '
@echo ' help - (this message)'
@echo ' all - build all XEPs (html and pdfs)'
@echo ' pdf - build all XEPs'
@echo ' html - build all XEPs'
@echo ' clean - recursively unlink the build tree'
@echo ' preview - builds html whenever an XEP changes (requires inotify-tools)'
@echo ' xep-xxxx - build xep-xxxx.html and xep-xxxx.pdf'
@echo ' xep-xxxx.html - build xep-xxxx.html'
@echo ' xep-xxxx.pdf - build xep-xxxx.html'
@echo ' '
@echo 'Output directory: "$(OUTDIR)/"'
.PHONY: all
all: html pdfs
.PHONY: html
html: $(patsubst %.xml, $(OUTDIR)/%.html, $(wildcard *.xml))
.PHONY: pdf
pdf: $(patsubst %.xml, $(OUTDIR)/%.pdf, $(wildcard *.xml))
.PHONY: xep-%
xep-%: $(OUTDIR)/xep-%.html $(OUTDIR)/xep-%.pdf ;
.PHONY: xep-%.html
xep-%.html: $(OUTDIR)/xep-%.html ;
.PHONY: xep-%.pdf
xep-%.pdf: $(OUTDIR)/xep-%.pdf ;
$(OUTDIR)/%.html: %.xml $(XMLDEPS)
xsltproc --path $(CURDIR) xep.xsl "$<" > "$@" && echo "Finished building $@"
$(OUTDIR)/%.pdf: %.xml $(TEMPDIR)/%.xml.texml $(TEMPDIR)/%.xml.texml.tex $(TEXMLDEPS)
cd $(TEMPDIR); xelatex $(TEMPDIR)/$<.texml.tex
mv $(TEMPDIR)/$<.texml.pdf $(OUTDIR)/$(patsubst %.xml.pdf,%.pdf,$<.pdf)
echo "Finished building $(patsubst %.xml.pdf,%.pdf,$<.pdf)"
$(TEMPDIR)/%.xml.texml: %.xml $(TEXMLDEPS) $(TEMPDIR)
xsltproc -o $(TEMPDIR)/$<.texml xep2texml.xsl "$<"
$(TEMPDIR)/%.xml.texml.tex: $(TEMPDIR)/%.xml.texml $(OUTDIR) $(TEMPDIR)
texml -e utf8 $< $<.tex
sed -i -e 's|\([\s"]\)\([^"]http\://[^ "]*\)|\1\\path{\2}|g' \
-e 's|\\hyperref\[#\([^}]*\)\]|\\hyperref\[\1\]|g' \
-e 's|\\pageref{#\([^}]*\)}|\\pageref{\1}|g' $<.tex
$(RESOURCESDIR)/xmpp-text.pdf: $(RESOURCESDIR)
curl -o $@ $(XMPPIMAGESURL)/xmpp-text.pdf
$(RESOURCESDIR)/xmpp.pdf: $(RESOURCESDIR)
curl -o $@ $(XMPPIMAGESURL)/images/xmpp.pdf
$(TEMPDIR) $(OUTDIR) $(RESOURCESDIR):
mkdir -p $@
.PHONY: clean
clean:
rm -rf $(OUTDIR)
.PHONY: preview
preview:
inotifywait -m -e close_write,moved_to --format '%e %w %f' $(XEPDIRS) | \
while read -r event dir file; do \
if [ "$${file: -4}" == ".xml" ]; then \
xsltproc --path $(CURDIR) xep.xsl "$${dir}/$${file}" > "$(OUTDIR)/$${file%.*}.html" && echo "Built $${file%.*}.html $${event}"; \
fi \
done

View File

@ -13,7 +13,7 @@ Please use this repository to raise issues and submit pull requests:
https://github.com/xsf/xeps/issues
https://github.com/xsf/xeps/pulls
For in-depth technical discussion, please post to the standards@xmpp.org
For in-depth technical discussion, please post to the standards@xmpp.org
email list:
http://mail.jabber.org/mailman/listinfo/standards
@ -23,5 +23,18 @@ page:
http://xmpp.org/xmpp-protocols/xmpp-extensions/submitting-a-xep/
Thanks!
[XEP-0001: XMPP Extension Protocols](http://xmpp.org/extensions/xep-0001.html)
defines the standards process followed by the XMPP Standards Foundation.
Building XEPs
-------------
To build a single XEP as HTML simply run:
make xep-xxxx
To change the output directory, set the variable `OUTDIR`, eg.
OUTDIR=/tmp/xeps make all
For more information try `make help`.

179
inbox/attachto.xml Normal file
View File

@ -0,0 +1,179 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Message Attaching</title>
<abstract>
This specification defines a method for indicating that a message contains
content which describes an earlier message in the conversation and should
be grouped with the earlier message.
</abstract>
&LEGALNOTICE;
<number>XXXX</number>
<status>ProtoXEP</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>message-attaching</shortname>
&sam;
<author>
<firstname>Craig</firstname>
<surname>Petchell</surname>
<email>cpetchell@atlassian.com</email>
</author>
<revision>
<version>0.0.1</version>
<date>2015-10-16</date>
<initials>ssw</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>
Many messaging applications send special messages which include more
information about a previous message. For example, when sending a link the
service may display the description or an image off the page, or users may
respond to a message with a "sticker" or an "emotion" which they wish to
display alongside the message, even though the conversation has moved on.
</p>
<p>
This specification defines a way by which one can indicate that a message
is logically (and visibly) "attached" to an earlier message in the
conversation.
</p>
</section1>
<section1 topic='Discovering support' anchor='disco'>
<p>
If a client implements message attaching, it MUST specify the
'urn:xmpp:message-attaching:0' feature in its service discovery information
features as specified in &xep0030; and the Entity Capabilities profile
specified in &xep0115;.
</p>
<example caption='Client requests information about a chat partner&apos;s client'><![CDATA[
<iq type='get'
from='alonso@naples.lit/ship'
id='miuARo9V'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>]]></example>
<example caption='Partner&apos;s client advertises support for attaching'><![CDATA[
<iq type='result'
to='alonso@naples.lit/ship'
from='naples.lit'
id='miuARo9V'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<feature var='urn:xmpp:message-attaching:0'/>
</query>
</iq>]]></example>
</section1>
<section1 topic='Usage' anchor='usage'>
<p>
Messages that are attached to other messages MUST contain an
&lt;attach-to/&gt; element qualified by the 'urn:xmpp:message-attaching:0'
namespace and with an 'id' attribute set to the ID of the message that we
want to attach to. Messages MAY be attached to any other message, including
those sent by other clients, but clients MAY choose to ignore the attach-to
directive and display the message normally.
</p>
<example caption='User attaches a message'><![CDATA[
<message to='antonio@milan.lit/ship' from='prospero@milan.lit/island id='RgEGnjqy'>
<body>storm.png</body>
<attach-to id='oldmessage1' xmlns='urn:xmpp:message-attaching:0'/>
</message>]]></example>
<p>
Note that indicating that a message should be "attached" to an earlier
message in the conversation is merely a suggestion to the client to display
the message next to or below the old message.
</p>
</section1>
<section1 topic='Business Rules' anchor='rules'>
<p>
A receiving client MAY choose to show the attached message next to or below
the indicated message in whatever display is used for messages or can
choose to display the attachment in another way (including as a normal
message, completely ignoring the attach-to element).
</p>
<p>
A receiving client SHOULD indicate that the message is an attachment, and
not a part of the original message to prevent confusion.
</p>
<p>
&lt;attach-to/&gt; elements MUST NOT be put on any stanza type other than
messages.
</p>
<p>
A server may choose to strip some &lt;attach-to/&gt; messages based on
local policy (eg. a server might have a policy that only it can create
message attachments).
</p>
<p>Clients MUST send ids on messages if they support attachments.</p>
<p>
Messages MUST NOT contain more than one &gt;attach-to/&lt; element.
</p>
<p>
Clients and servers MUST NOT include an &lt;attach-to/&gt; element on
messages with a non-messaging payload unless they are including it on an
error which may be attached to the message that caused the error to be
generated.
</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
Clients that implement message attachments MUST be careful not to display the
attachments in such a way that they could be confused with the original
message and cause someone viewing the conversation to assume they were sent
by the sender of the message being attached to.
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with &IANA;.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<p>This specification defines the following XML namespaces:</p>
<ul>
<li>urn:xmpp:message-attaching:0</li>
</ul>
<p>
The &REGISTRAR; shall include the foregoing namespaces in its disco
features registry as defined in &xep0030;.
<code caption='Registry Submission'><![CDATA[
<var>
<name>urn:xmpp:message-attaching:0</name>
<desc>Indicates support for attaching one message to another.</desc>
<doc>XEP-xxxx</doc>
</var>
]]></code>
</p>
</section1>
<section1 topic='XML Schema' anchor='schema'>
<code><![CDATA[
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:xmpp:message-attaching:0'
xmlns='urn:xmpp:message-attaching:0'
elementFormDefault='qualified'>
<xs:element name='attach-to'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='id' type='xs:string' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
]]></code>
</section1>
</xep>

611
inbox/entityversioning.xml Normal file
View File

@ -0,0 +1,611 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Entity Versioning</title>
<abstract>
A method by which lists of items may be versioned so that servers will not
need to send the entire list if it has not been modified, saving bandwidth
and time with minimal state being stored by the server and client.
</abstract>
&LEGALNOTICE;
<number>xxxx</number>
<status>ProtoXEP</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>RFC 6120</spec>
<spec>RFC 6121</spec>
</dependencies>
<supersedes />
<supersededby />
<shortname>EV</shortname>
<author>
<firstname>Sam</firstname>
<surname>Whited</surname>
<email>swhited@atlassian.com</email>
<jid>sam@samwhited.com</jid>
</author>
<author>
<firstname>Doug</firstname>
<surname>Keen</surname>
<email>dkeen@atlassian.com</email>
</author>
<revision>
<version>0.0.2</version>
<date>2015-09-17</date>
<initials>ssw</initials>
<remark><p>Add profiles / partial sync.</p></remark>
</revision>
<revision>
<version>0.0.1</version>
<date>2015-08-25</date>
<initials>ssw</initials>
<remark><p>First draft</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>
This problem of "downloading the world" (downloading the entire roster
every time a session is initialized or receiving an entire disco items
response every time a MUC list is queried, etc.) was partially addressed by
&xep0237; which was later merged into &rfc6121; §2.6. While this solved
the problem for the roster, it didn't account for other entities.
Furthermore, roster versioning requires that the server maintain a great
deal of state (roster items which should be pushed for each entity on
reconnect, or monotonically increasing counters, etc.) which can be
difficult to store or synchronize in a large, distributed system. This XEP
defines a method by which generic entity lists can be versioned and cached,
and which is optimized for distributed systems with large entity lists (but
works equally well on small, single server deployments).
</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<ul>
<li>
An extra round trip MUST NOT be required to initiate entity versioning.
</li>
<li>
Clients that do not implement the protocol (but which use servers that
do) MUST still be able to request and receive entities normally.
</li>
<li>
Servers which implement this protocol MUST NOT be required to store
multiple versions of an entity list or maintain other redundant state.
</li>
<li>
Inconsistant state between servers in a cluster should not cause cache
invalidation for the entire entity list.
</li>
<li>
Large changes SHOULD NOT be required for existing servers / clients.
</li>
</ul>
</section1>
<section1 topic='Glossary' anchor='glossary'>
<dl>
<dt>Aggregate Token</dt>
<dd>
A hash which represents the state of a list of entities, and changes if
any of those entities changes.
</dd>
<dt>Versioned Entity</dt>
<dd>Any abstract object which may be versioned (eg. rooms, users).</dd>
<dt>Version Token</dt>
<dd>
A short, case sensitive string which represents an entity and changes if
that entity changes.
</dd>
</dl>
</section1>
<section1 topic='Use Cases' anchor='use_cases'>
<section2 topic='Clients' anchor='client_use_cases'>
<ul>
<li>
A client on a mobile device where bandwidth and throughput are limited
has a very large roster which cause connections to take an unacceptable
amount of time. With entity versioning, connections after the first
connection do not take as long, and use less bandwidth.
</li>
<li>
A client often wants to view the list of multi-user chat rooms
available on a servers MUC service. However, the list is very long and
takes a long time to download. After enabling entity versioning the
client can fetch the list, and then poll for changes at a later date
without re-requesting the entire list.
</li>
<li>
A client wishes to cache the features supported by servers of the
contacts in their roster since their disco items is not likely to
change often.
</li>
</ul>
</section2>
<section2 topic='Servers' anchor='server_use_cases'>
<ul>
<li>
A server is running in an environment where storing multiple versions
of each users roster may put too much pressure on the storage backend.
After enabling entity versioning, they only have to store a small token
per user and can calculate the diffs to send to the client afterwards.
</li>
<li>
A server maintains an out-of-band HTTP API for fetching information
about MUC rooms to display on their web page. They wish to use a
reverse proxy to cache API requests based on etags. Instead of
attempting to check if the backend page has changed and generate etags,
the room's entity version token is used as a weakly-validated ETag.
</li>
</ul>
</section2>
</section1>
<section1 topic='Entity Versioning Profiles' anchor='profiles'>
<p>
Because entity versioning is designed to be a generic system for syncing
any sort of list in XMPP, and the format and requirements of various entity
lists may vary greatly, no specific wire format is defined in this
specification. Instead, the specifics for various lists will be left up to
separate XEPs which will define entity versioning "profiles" which must be
registered with the XMPP registrar. These profiles will define exactly how
version tokens are represented in the specific list format for which they
wish to use entity versioning. The rest of this document will provide
details about entity versioning which will be common to all entity
versioning profiles and do not need to be redefined in EV profile XEPs. It
will also define an EV profile for fetching the roster.
</p>
<p>
The roster entity versioning profile which is used as an example throughout
this document will use the namespace 'urn:xmpp:entityver:profile:roster:0'
as described in the <link url="#registrar">XMPP Registrar
Considerations</link> section of this document.
</p>
</section1>
<section1 topic='Discovering Support' anchor='disco'>
<p>
If a server supports entity versioning, it MUST inform the connecting
client when returning stream features during the stream negotiation
process. This is done by including a &lt;ver/&gt; element, qualified by the
'urn:xmpp:entityver:0' namespace with child &lt;profile&gt; nodes for each
supported entity versioning profile. At the latest, this SHOULD be done
when informing a client that resource binding is required. For example if
the server only supports versioning of rosters it might return:
</p>
<example caption="Stream Features"><![CDATA[
<stream:features>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
<required/>
</bind>
<ver xmlns='urn:xmpp:entityver:0'>
<profile xmlns='urn:xmpp:entityver:profile:roster:0'/>
</ver>
</stream:features>
]]></example>
<p>
The entity versioning stream feature is merely informative and therefore
is never mandatory-to-negotiate.
</p>
<p>
Clients, servers, and other entities that support &xep0030; and entity
versioning must respond to service discovery requests with a feature of
'urn:xmpp:entityver:0' and with a feature for each EV profile supported by
the responding entity as described in the relavant specifications. Eg. a
response from a server that supports roster versioning for the requesting
entity might look like the following:
<example caption="Service discovery information response"><![CDATA[
<iq from='shakespeare.lit'
id='ku6e51v3'
to='kingclaudius@shakespeare.lit/castle'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<feature var='urn:xmpp:entityver:0'/>
<feature var='urn:xmpp:entityver:profile:roster:0'/>
</query>
</iq>
]]></example>
</p>
</section1>
<section1 topic='Entity Sync' anchor='entity_sync'>
<section2 topic='Version Tokens' anchor='version_tokens'>
<p>
Version tokens are short case-sensitive strings which are generated by
the server. Their format is not defined in this spec, but a
recommendation may be found in the <link url="#impl">Implementation
Notes</link>. Version tokens are akin to a weakly-validated etag for the
entity in question.
</p>
<p>
Servers that implement this protocol must assign such a version token to
each entity that is controlled by the server. The server SHOULD then
update this version every time any mutable property of the entity changes
(eg. when the subscription status of a user changes). The server MAY
choose to update this token at any time (to force the clients to
invalidate their cached representation fo the object). This version token
MUST then be included with every object representation of that entity
sent down in the stream. This is done by including a sub-node called
"version" qualified by the entity versioning XML namespace defined in
this document. Similarly, clients MAY also add version nodes for each
version token they possess to the request for a list (not specifying a
version token will force the server to send information on that entity to
the client). If a server sends up a list of version tokens, the server
MUST then check to see if those tokens correspond to any entity which it
knows about, and not send down any entities with matching version tokens
in the response.
</p>
<p>
For example, a versioned roster request might look like this:
<example caption="Roster Request"><![CDATA[
<!-- Client -->
<iq from='romeo@montague.lit/home' id='56' to='romeo@montague.lit' type='get'>
<query xmlns='jabber:iq:roster'>
<item jid='bill@shakespeare.lit'>
<version xmlns='urn:xmpp:entityver:0'>25P2A7H8</version>
</item>
<item jid='anne@shakespeare.lit'>
<version xmlns='urn:xmpp:entityver:0'>VIZSVF0D</version>
</item>
</query>
</iq>
<!-- Server -->
<iq from='romeo@montague.lit' id='56' to='romeo@montague.lit/home' type='result>
<query xmlns='jabber:iq:roster'>
<item subscription='both' jid='bill@shakespeare.lit'>
<version xmlns='urn:xmpp:entityver:0'>9ZFZXVP9</version>
</item>
</query>
</iq>
]]></example>
</p>
<p>
Note that in this case there may be three roster items total (and the
client only knows about two of them), or there may be two total roster
items and the server is informing the client about a change to
"bill@shakespeare.lit". Version tokens MUST also be present in roster
pushes:
<example caption="Roster Push"><![CDATA[
<iq from='romeo@montague.lit' id='ah382g678jka7' to='romeo@montague.lit/home' type='set'>
<query xmlns='jabber:iq:roster' ver='ver34'>
<item jid='tybalt@shakespeare.lit' subscription='remove'>
<version xmlns='urn:xmpp:entityver:0'>XWE4MUUP</version>
</item>
</query>
</iq>
]]></example>
</p>
</section2>
<section2 topic='Cache Invalidation' anchor='deletes'>
<p>
When a client syncs with the server and indicates that it has a version
token in its cache that does not match any entity on the server (or when
the server wants to remove an entity from the clients cache for any other
reason), the server MUST reply with an empty &lt;version/&gt; node. When
the client receives such an empty version node it SHOULD purge the entity
from its cache. For example, the following would remove the roster item
'bill@shakespeare.lit' from the cache:
<example caption="Cache invalidation"><![CDATA[
<iq from='romeo@montague.lit' id='56' to='romeo@montague.lit/home' type='result>
<query xmlns='jabber:iq:roster'>
<item subscription='both' jid='bill@shakespeare.lit'>
<version xmlns='urn:xmpp:entityver:0'/>
</item>
</query>
</iq>
]]></example>
</p>
<p>
Roster pushes that indicate a deleted item MUST also remove the version
from the cache (and need not contain an empty &lt;version/&gt; element).
</p>
</section2>
<section2 topic='Partial sync'>
<p>
For very large groups fetching an entire list may not be practical or
necessary. For example, one might imagine a large corporation with a
shared roster that is too large for its version tokens to be sent up to
the server on every sync, or even to download fully the first time. To
solve this, servers MAY choose to send down only a part of an entity list
in response to a query (unless the individual EV profile forbids partial
list sync). How servers choose what items to return is an implementation
detail that is out of the scope of this document. Some suggestions may be
found in the <link url="#impl">Implementation Notes</link>. On subsequent
requests for the entity list, the server MAY choose to return more
entities (eg. based on changes in its internal selection criteria),
however it MUST NOT invalidate cached entities unless they have actually
been removed from the list.
</p>
<p>
XEPs defining entity versioning profiles MUST include a section to
indicate if partial sync is supported, and if so, how it will be
indicated to the client (and how the client can request a full list). If
no mechanism is specified, this is done by adding a boolean "full_list"
attribute to the request, eg. a roster request for a partial list looks
like:
<example caption="Roster Request"><![CDATA[
<!-- Client -->
<iq from='romeo@montague.lit/home'
id='56'
to='romeo@montague.lit'
type='get'>
<query xmlns='jabber:iq:roster' full_list='false'>
<item jid='bill@shakespeare.lit'>
<version xmlns='urn:xmpp:entityver:0'>25P2A7H8</version>
</item>
<item jid='anne@shakespeare.lit'>
<version xmlns='urn:xmpp:entityver:0'>VIZSVF0D</version>
</item>
</query>
</iq>
<!-- Server -->
<iq from='romeo@montague.lit' id='56' to='romeo@montague.lit/home' type='result'>
<query xmlns='jabber:iq:roster' full_list='false'>
<item subscription='both' jid='bill@shakespeare.lit'>
<version xmlns='urn:xmpp:entityver:0'>9ZFZXVP9</version>
</item>
</query>
</iq>
]]></example>
</p>
<p>
When making a request for a partial list, clients do not need to send up
every entity in their cache. Instead they MAY send up just those entities
for which they wish to check for updates. The server MUST then respond
with any updates for those entities, and MAY also add other entities to
the list if desired. If the client requests a partial list but does not
indicate that it has anything in its cache, what entities to return (if
any) is left up to the server implementation.
</p>
</section2>
<section2 topic='List search'>
<p>
When a client has an incomplete versioned list, it may be beneficial to
download more of the list without requesting the full list. To do this,
servers which support entity versioning MUST supply a "search" IQ which
can be used to discover list items matching a certain criteria. What data
to match on (JID, metadata, associated vcards, etc.), and what type of
search are left up to the server implementation and MAY be different
between profiles.
</p>
<p>
Search queries are qualified by the 'urn:xmpp:entityver:0:search'
namespace and MUST have a 'profile' attribute set to the namespace for
which the search is being performed. For instance, searching the roster
looks like the following:
<example caption="Roster search"><![CDATA[
<!-- Client -->
<iq from='romeo@montague.lit/home'
id='564'
to='romeo@montague.lit'
type='get'>
<query xmlns="urn:xmpp:entityver:0:search" profile='urn:xmpp:entityver:profile:roster:0'>
Search term
</query>
</iq>
<!-- Server -->
<iq from='romeo@montague.lit' id='564' to='romeo@montague.lit/home' type='result'>
<query xmlns="urn:xmpp:entityver:0:search" profile='urn:xmpp:entityver:profile:roster:0' type='result'>
<item subscription='both' jid='matching_search@term.lit'>
<version xmlns='urn:xmpp:entityver:0'>4YAZ7Y38</version>
</item>
</query>
</iq>
]]></example>
</p>
<p>
Search results SHOULD be added to the given list's cache. In this way,
the full list does not need to be known.
</p>
</section2>
<section2 topic='Aggregate Tokens' anchor='agg_tokens'>
<p>
While the version token approach to caching does not require a great deal
of state to be stored on the client or the server, it does require a lot
more information to be sent by the client when requesting a list of
entities. For a very large list which is not likely to have changed, it
may be useful know in advance if the roster has changed or not (so that
we can avoid sending the large request entirely). To do this, we can
request an aggregate version token from the server. This aggregate token
is calculated by constructing a string of comma separated "ID:version"
pairs sorted in byte-wise order (because the ID:version pair is
constructed before sorting, if two items in the list have the same ID
they can still be sorted by the version token), and taking the MD5 hash
of the constructed string. The ID in the pair is any ID or key that
identifies the entity as defined in its profile (eg. a JID for roster
items and most other entities). For example, if the server is calculating
the aggregate version token for a roster, it might end up with the
following string:
</p>
<example caption="Aggregate token list"><![CDATA[
anne@shakespeare.lit:VIZSVF0D,bill@shakespeare.lit:25P2A7H8
]]></example>
<p>
Which results in the aggregate token:
</p>
<example caption="Aggregate token"><![CDATA[
0514fc90e6c7981b06bbb2173bb8ef03
]]></example>
<p>
The actual request is an IQ sent to the server, or entity handling the
versioned list which contains a query that specifies the namespace of the
list we want to fetch. Eg. to fetch the aggregate token for the roster
one would query the server with the query's XMLNS set to
'urn:xmpp:entityver:profile:roster:0':
</p>
<example caption="Roster aggregate token request"><![CDATA[
<!-- Client -->
<iq to='bill@shakespeare.lit' type='get' id='bill1'>
<query xmlns='urn:xmpp:entityver:profile:roster:0'/>
</iq>
<!-- Server -->
<iq to='bill@shakespeare.lit/home' type='result' id='bill1'>
<query xmlns='urn:xmpp:entityver:profile:roster:0'>
0514fc90e6c7981b06bbb2173bb8ef03
</query>
</iq>
]]></example>
<p>
Because aggregate tokens are OPTIONAL to implement, clients MUST fall
back to making a normal list request if any error is returned in response
to an aggregate token IQ.
</p>
<p>
If an aggregate token is requested for a list that may contain more than
one type of entity (eg. MUC rooms and pubsub nodes that live on the same
component), then the server MUST return the aggregate token constructed
with the entire list (rooms and pubsub nodes).
</p>
<p>
Because aggregate tokens are calculated for the entire list as seen by
the client or server, they will never match if partial lists have been
downloaded by the client.
</p>
<p>
Clients are also NOT REQUIRED to check aggregate tokens. However, clients
MAY wish to check aggregate tokens before making a roster or MUC request
when the cached roster or MUC list is very large. When to check aggregate
tokens (if at all) is left up to the implementation.
</p>
</section2>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
<p>
Version tokens may not provide enough collision resistance across versioned
entities (hereafter simply called "entities"), and may vary from server to
server, and therefore they MUST NOT be used as an entity identifier.
</p>
<p>
Version tokens SHOULD always be considered opaque to the client (eg. even
if the version token is a derivable and consistent hash on the server side,
clients should not need to know how the server is calculating the token).
</p>
<p>
The author RECOMMENDS using 8 character (32-bit) random alphanumeric ASCII
strings (eg. AABd7z9T) for version tokens.
</p>
<p>
If a server which supports this XEP provides an HTTP API which can be used
to fetch information about entities (eg. for listing information about MUC
rooms that a server provides on the providers web page), the entities
version token MAY be used as a weakly validated ETag for any API requests
for that entity.
</p>
<p>
Servers following this specification may choose to send down partial entity
lists in response to queries. For the case of rosters one or more of the
following may be returned to the requesting entity during the initial
roster sync:
<ul>
<li>
Users that are grouped with the requester in some way. Eg. for a
company with a large shared roster which places the requesting client
in the "Marketing Department" group, the server may wish to return
roster items that also share that group.
</li>
<li>Users whom the requester has contacted recently or frequently.</li>
<li>Users that should always be returned as part of server policy.</li>
</ul>
</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>
Client-side caching of entity information across sessions (rather than
holding them in memory only for the life of a session) could pose a privacy
risk, especially on shared systems. Implementations SHOULD protect cached
entity data with strong encryption or other appropriate means.
</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with &IANA;.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>This specification defines the following XML namespace:</p>
<ul>
<li>urn:xmpp:entityver:0</li>
<li>urn:xmpp:entityver:0:search</li>
</ul>
<p>
Upon advancement of this specification from a status of Experimental to a
status of Draft, the &REGISTRAR; shall add the foregoing namespace to the
registry located at &STREAMFEATURES;, as described in Section 4 of
&xep0053;.
</p>
</section2>
<section2 topic='Namespace Versioning' anchor='registrar-versioning'>
&NSVER;
</section2>
<section2 topic='Entity Versioning Profiles Registry' anchor='registrar-ev'>
<p>
The XMPP Registrar shall maintain a registry of entity versioning
profiles. All EV profile registrations shall be defined in separate
specifications (not in this document). Application types defined within
the XEP series MUST be registered with the XMPP Registrar, resulting in
protocol URNs of the form "urn:xmpp:entityver:profile:name:X" (where
"name" is the registered name of the profile and "X" is a non-negative
integer).
</p>
&REGPROCESS;
<code><![CDATA[
<profile>
<name>The name of the entity versioning profile.</name>
<desc>A natural-language summary of the profile.</desc>
<listdef>
The document in which the original list definition is specified.
</listdef>
<doc>
The document in which the EV profile for the list is specified (may be the
same as <listdev/>).
</doc>
</profile>
]]></code>
</section2>
<section2 topic='Entity Versioning Profiles' anchor='registrar-evprofile'>
<p>This specification defines the following entity versioning profile:</p>
<ul>
<li>urn:xmpp:entityver:profile:roster:0</li>
</ul>
<p>
Upon advancement of this specification from a status of Experimental to a
status of Draft, the &REGISTRAR; shall add the following definition to
the entity versioning profiles registry, as described in this document:
<code><![CDATA[
<profile>
<name>Roster entity versioning</name>
<desc>Allows versioning of entities in an XMPP roster.</desc>
<listdef>RFC 6121</listdef>
<doc>TODO: Insert this document once it is assigned a number</doc>
</profile>
]]></code>
</p>
</section2>
</section1>
<section1 topic='XML Schema' anchor='schema'>
TODO
</section1>
<section1 topic='Acknowledgements' anchor='ack'>
<p>
The original entity versioning proposal was engineered and written by
HipChat's Doug Keen.
</p>
</section1>
</xep>

View File

@ -0,0 +1,618 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Jingle HTTP Transport Method</title>
<abstract>This specification defines two Jingle transport methods for establishing HTTP connections for either uploading or downloading data.</abstract>
&LEGALNOTICE;
<number>xxxx</number>
<status>ProtoXEP</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>XEP-0166</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
&lance;
<revision>
<version>0.0.1</version>
<date>2015-07-30</date>
<initials>ljts</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>&xep0166; defines a framework for negotiating and managing out-of-band data sessions over XMPP. In order to provide a flexible framework, the base Jingle specification defines neither data transport methods nor application formats, leaving that up to separate specifications.</p>
<p>The current document defines two transport methods for establishing and managing data exchanges between XMPP entities using the Hyper Text Transfer Protocol (HTTP, see &rfc2616;); one method is for sharing via pulling data from an HTTP URI (http-download), and the other is for sharing via pushing data to an HTTP URI (http-upload).</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<p>Historically, &xep0066; has been used to trigger downloading files via HTTP, as well as initiating the use of any other known URI scheme. However, it has several limitations:</p>
<ul>
<li>It only allows for the downloading of files via HTTP, not uploading.</li>
<li>It can not specify any additional headers that might be necessary for downloading files (authentication tokens, etc).</li>
<li>The allowance of any URI scheme makes it too unwieldy to be integrated into Jingle the way SOCKS5 Bytestreams and In-Band Bytestreams were (see &xep0260; and &xep0261;).</li>
</ul>
<p>As such, this document defines two Jingle mechanisms designed to meet the following requirements:</p>
<ul>
<li>Allow for both uploading and downloading of data via HTTP.</li>
<li>Allow additional HTTP headers to be specified.</li>
<li>Restrict the URI scheme to HTTP/HTTPS.</li>
</ul>
</section1>
<section1 topic='Jingle Conformance' anchor='conformance'>
<p>In accordance with Section 12 of <cite>XEP-0166</cite>, this document specifies the following information related to both the Jingle http-download and http-upload transport methods:</p>
<ol>
<li><p>The transport negotiation process for http-download is defined in the <link url='#download'>Negotiating HTTP Download</link> section of this document, and the negotation process for http-upload is defined in the <link url='#upload'>Negotiating HTTP Upload</link> section of this document.</p></li>
<li><p>The semantics of the &TRANSPORT; element are defined in the <link url='#download'>Negotiating HTTP Download</link> and <link url='#upload'>Negotiating HTTP Upload</link> sections of this document.</p></li>
<li><p>Successful negotiation of both the http-download and http-upload methods results in use of a streaming transport method suitable for use in Jingle application types where packet loss cannot be tolerated (e.g., file transfer).</p></li>
<li><p>Multiple components are not supported by http-download or http-upload.</p></li>
</ol>
</section1>
<section1 topic='Negotiating HTTP Download' anchor='download'>
<p>Negotiating HTTP downloads is done by using a &TRANSPORT; element with the 'urn:xmpp:jingle:transports:http:0' namespace, &VNOTE;. This element MAY include &lt;candidate/&gt; elements which represent URIs where data can be downloaded. Each &lt;candidate/&gt; element MUST include a 'uri' attribute, and MAY contain &lt;header/&gt; elements whose 'name' attribute is an HTTP header and whose text content is the HTTP header value.</p>
<code><![CDATA[
<transport xmlns='urn:xmpp:jingle:transports:http:0'>
<candidate uri='https://files.montague.example/ERUN8970'>
<header name='authorization'>Bearer 7472327205ffb74d10b11363044d8c24e3ddba12</header>
</candidate>
</transport>]]></code>
<p>Multiple candidates MAY be provided, indicating that there are multiple URIs from which the data can be retrieved (e.g. multiple candidates could be included to list the primary URI of a file along with several known mirrors).</p>
<code><![CDATA[
<transport xmlns='urn:xmpp:jingle:transports:http:0'>
<candidate uri='https://files.montague.example/ERUN8970' />
<candidate uri='https://mirror1.montague.example/ERUN8970' />
<candidate uri='https://mirror2.montague.example/ERUN8970' />
</transport>]]></code>
<p>The generation of candidates is based on the Jingle content senders, and only the parties specified to send data SHOULD provide candidates.</p>
<p>Upon receiving an HTTP download candidate, parties that are to receive data (based on the Jingle content senders) SHOULD use an HTTP GET request to the candidate URI to fetch the data.</p>
<p>Entities MAY initially provide an empty set of candidates if a suitable download URI is not yet known; advertising candidates later is done with transport-info actions.</p>
<table caption='Summary of Roles in Jingle HTTP Download'>
<tr>
<th>Content Creator</th>
<th>Content Senders</th>
<th>Who Sends Download Candidates</th>
<th>Who performs HTTP GET</th>
</tr>
<tr>
<td rowspan='4'>initiator</td>
<td>initiator</td>
<td>initiator</td>
<td>responder</td>
</tr>
<tr>
<td>responder</td>
<td>responder</td>
<td>initiator</td>
</tr>
<tr>
<td>both</td>
<td>both</td>
<td>both</td>
</tr>
<tr>
<td>none</td>
<td>none</td>
<td>none</td>
</tr>
<tr>
<td rowspan='4'>responder</td>
<td>initiator</td>
<td>initiator</td>
<td>responder</td>
</tr>
<tr>
<td>responder</td>
<td>responder</td>
<td>initiator</td>
</tr>
<tr>
<td>both</td>
<td>both</td>
<td>both</td>
</tr>
<tr>
<td>none</td>
<td>none</td>
<td>none</td>
</tr>
</table>
</section1>
<section1 topic='Negotiating HTTP Upload' anchor='upload'>
<p>Negotiating HTTP uploads is done by using a &TRANSPORT; element with the 'urn:xmpp:jingle:transports:http:upload:0' namespace, &VNOTE;. This element MAY include a &lt;candidate/&gt; element which represents a URI where data can be uploaded. The &lt;candidate/&gt; element MUST include a 'uri' attribute, and MAY contain &lt;header/&gt; elements whose 'name' attribute is an HTTP header and whose text content is the HTTP header value.</p>
<code><![CDATA[
<transport xmlns='urn:xmpp:jingle:transports:http:upload:0'>
<candidate uri='https://files.montague.example/ERUN8970'>
<header name='authorization'>Bearer 7472327205ffb74d10b11363044d8c24e3ddba12</header>
</candidate>
</transport>]]></code>
<p>The generation of candidates is based on the Jingle content senders, and only the parties specified to receive data SHOULD provide candidates.</p>
<p>Upon receiving an HTTP upload candidate, parties that are to send data (based on the Jingle content senders) SHOULD use an HTTP PUT request to the candidate URI, where the request body is the data to be transferred.</p>
<table caption='Summary of Roles in Jingle HTTP Upload'>
<tr>
<th>Content Creator</th>
<th>Content Senders</th>
<th>Who Sends Upload Candidates</th>
<th>Who Performs HTTP PUT</th>
</tr>
<tr>
<td rowspan='4'>initiator</td>
<td>initiator</td>
<td>responder</td>
<td>initiator</td>
</tr>
<tr>
<td>responder</td>
<td>initiator</td>
<td>responder</td>
</tr>
<tr>
<td>both</td>
<td>both</td>
<td>both</td>
</tr>
<tr>
<td>none</td>
<td>none</td>
<td>none</td>
</tr>
<tr>
<td rowspan='4'>responder</td>
<td>initiator</td>
<td>responder</td>
<td>initiator</td>
</tr>
<tr>
<td>responder</td>
<td>initiator</td>
<td>responder</td>
</tr>
<tr>
<td>both</td>
<td>both</td>
<td>both</td>
</tr>
<tr>
<td>none</td>
<td>none</td>
<td>none</td>
</tr>
</table>
<p>See <link url='#upload-complete'>Upload Complete</link> for signaling that the upload process has been completed.</p>
</section1>
<section1 topic='Informational Messages' anchor='info'>
<section2 topic='Upload Complete'>
<p>A common case for using http-upload is to delegate the storage of the uploaded data to an external hosting service, which means that the receiver might not have the direct ability to know when the uploaded data is ready.</p>
<p>As such, when an upload transfer is used, the party uploading content SHOULD signal when the upload has completed by sending a Jingle session-info event that includes a &lt;uploaded/&gt; element qualified by the 'urn:xmpp:transports:http:info:0' namespace and SHOULD include 'creator' and 'name' attributes identifying the content for which the upload was completed.</p>
<example caption='Signaling that the upload has completed'><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='uw72g176'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-info'>
<uploaded xmlns='urn:xmpp:jingle:transports:http:info:0' creator='initiator' name='file-upload' />
</jingle>
</iq>]]></example>
</section2>
</section1>
<section1 topic='Examples'>
<section2 topic='Offering a File using HTTP Download'>
<p>Here, Romeo is offering to send a file to Juliet, so he includes a download URI candidate with his session-initiate.</p>
<example caption='Offering a file with a download URI'><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='nzu25s8'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='851ba2'>
<content creator='initiator' name='a-file-offer' senders='initiator'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4'>
<file>
<date>1969-07-21T02:56:15Z</date>
<desc>This is a test. If this were a real file...</desc>
<media-type>text/plain</media-type>
<name>test.txt</name>
<range/>
<size>6144</size>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>
</file>
</description>
<transport xmlns='urn:xmpp:jingle:transports:http:0'>
<candidate uri='https://files.montague.example/test.txt' />
</transport>
</content>
</jingle>
</iq>]]></example>
<p>Juliet accepts the offer, and then performs an HTTP GET to retrieve the file.</p>
<example caption='Accepting an offered file using HTTP download'><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='nzu25s8'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-accept'
initiator='romeo@montague.lit/orchard'
sid='851ba2'>
<content creator='initiator' name='a-file-offer' senders='initiator'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4' />
<transport xmlns='urn:xmpp:jingle:transports:http:0' />
</content>
</jingle>
</iq>]]></example>
</section2>
<section2 topic='Requesting a File using HTTP Download'>
<p>Here Romeo is requesting Juliet to send a file by sharing a download URI.</p>
<example caption='Requesting a file and download URI'><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='nzu25s8'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='851ba2'>
<content creator='initiator' name='a-file-request' senders='responder'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4'>
<file>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>
</file>
</description>
<transport xmlns='urn:xmpp:jingle:transports:http:0' />
</content>
</jingle>
</iq>]]></example>
<p>Juliet accepts the request, and includes a download URI in her session-accept.</p>
<example caption='Returning download URI'><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='nzu25s8'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-accept'
sid='851ba2'>
<content creator='initiator' name='a-file-request' senders='responder'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4' />
<file>
<date>1969-07-21T02:56:15Z</date>
<media-type>text/plain</media-type>
<name>test.txt</name>
<range/>
<size>6144</size>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>
</file>
</description>
<transport xmlns='urn:xmpp:jingle:transports:http:0'>
<candidate uri='https://files.capulet.example/test.txt' />
</transport>
</content>
</jingle>
</iq>]]></example>
<p>Romeo then retrieves the file using an HTTP GET request.</p>
</section2>
<section2 topic='Offering a File using HTTP Upload'>
<p>In this case, Romeo is offering a file to Juliet but wishes to upload it to her.</p>
<example caption='Offering to upload a file'><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='nzu25s8'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='851ba2'>
<content creator='initiator' name='a-file-offer' senders='initiator'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4'>
<file>
<date>1969-07-21T02:56:15Z</date>
<desc>This is a test. If this were a real file...</desc>
<media-type>text/plain</media-type>
<name>test.txt</name>
<range/>
<size>6144</size>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>
</file>
</description>
<transport xmlns='urn:xmpp:jingle:transports:http:upload:0' />
</content>
</jingle>
</iq>]]></example>
<p>Juliet accepts, and provides a candidate with an upload URI that includes an authorization header.</p>
<example caption='Accepting the session and providing an upload URI'><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='nzu25s8'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-accept'
sid='851ba2'>
<content creator='initiator' name='a-file-request' senders='responder'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4' />
<transport xmlns='urn:xmpp:jingle:transports:http:upload:0'>
<candidate uri='https://files.capulet.example/ERIE32430'>
<header name='authorization'>Bearer 7472327205ffb74d10b11363044d8c24e3ddba12</header>
</candidate>
</transport>
</content>
</jingle>
</iq>]]></example>
<p>Romeo now uses an HTTP PUT to upload his file. Once the upload is complete, he informs Juliet so she knows the file is ready for to read.</p>
<example caption='Signaling that the upload has completed'><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='uw72g176'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-info'
sid='851ba2'>
<uploaded xmlns='urn:xmpp:jingle:transports:http:info:0' creator='initiator' name='file-upload' />
</jingle>
</iq>]]></example>
</section2>
<section2 topic='Requesting a File using HTTP Upload'>
<p>Here Romeo asks Juliet to upload a file.</p>
<example caption='Offering a file with a download URI'><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='nzu25s8'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='851ba2'>
<content creator='initiator' name='a-file-offer' senders='initiator'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4'>
<file>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>
</file>
</description>
<transport xmlns='urn:xmpp:jingle:transports:http:upload:0'>
<candidate uri='https://files.montague.example/test.txt' />
</transport>
</content>
</jingle>
</iq>]]></example>
<p>Juliet accepts the session, and begins uploading the file data with an HTTP PUT request.</p>
<example caption='Accepting the session'><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='nzu25s8'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-accept'
sid='851ba2'>
<content creator='initiator' name='a-file-request' senders='responder'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4' />
<file>
<date>1969-07-21T02:56:15Z</date>
<media-type>text/plain</media-type>
<name>test.txt</name>
<range/>
<size>6144</size>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>
</file>
</description>
<transport xmlns='urn:xmpp:jingle:transports:http:upload:0'>
</content>
</jingle>
</iq>]]></example>
<p>Once the upload is complete, she informs Romeo that she has completed the upload so that he knows he can access the data he requested.</p>
<example caption='Signaling that the upload has completed'><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='uw72g176'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-info'
sid='851ba2'>
<uploaded xmlns='urn:xmpp:jingle:transports:http:info:0' creator='initiator' name='file-upload' />
</jingle>
</iq>]]></example>
</section2>
</section1>
<section1 topic='Determining Support' anchor='support'>
<p>To advertise its support for the Jingle HTTP Transport Method, when replying to &xep0030; information requests an entity MUST return URNs for any version of this protocol that the entity supports -- e.g., "urn:xmpp:jingle:transports:http:0" for this version &VNOTE;.</p>
<example caption="Service discovery information request"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='uw72g176'
to='juliet@capulet.lit/balcony'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>]]></example>
<example caption="Service discovery information response"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='uw72g176'
to='romeo@montague.lit/orchard'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<feature var='urn:xmpp:jingle:1'/>
<feature var='urn:xmpp:jingle:transports:http:0'/>
<feature var='urn:xmpp:jingle:transports:http:upload:0'/>
</query>
</iq>]]></example>
<p>In order for an application to determine whether an entity supports this protocol, where possible it SHOULD use the dynamic, presence-based profile of service discovery defined in &xep0115;. However, if an application has not received entity capabilities information from an entity, it SHOULD use explicit service discovery instead.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>HTTP URI candidates SHOULD use the "https://" URI scheme instead of "http://", and entities MAY refuse to process URIs that are not "https://".</p>
<p>Certain HTTP headers can cause unintended behaviour, such as using the 'Upgrade' header to trigger a conversion to WebSocket (&rfc6455;).</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>No interaction with &IANA; is required as a result of this document.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>This specification defines the following XML namespaces:</p>
<ul>
<li>urn:xmpp:jingle:transports:http:0</li>
<li>urn:xmpp:jingle:transports:http:upload:0</li>
<li>urn:xmpp:jingle:transports:http:info:0</li>
</ul>
<p>The &REGISTRAR; includes the foregoing namespace in its registry of protocol namespaces at &NAMESPACES;, as described in Section 4 of &xep0053;.</p>
</section2>
<section2 topic='Namespace Versioning' anchor='registrar-versioning'>
&NSVER;
</section2>
<section2 topic='Jingle Transport Methods' anchor='registrar-content'>
<p>The &REGISTRAR; includes "http-download" in its registry of Jingle transport methods at &JINGLETRANSPORTS;. The registry submission is as follows:</p>
<code><![CDATA[
<transport>
<name>http-download</name>
<desc>
A method for negotiating data exchange via HTTP URI retrieval.
</desc>
<type>streaming</type>
<doc>XEP-XXXX</doc>
</transport>]]></code>
<p>The &REGISTRAR; includes "http-upload" in its registry of Jingle transport methods at &JINGLETRANSPORTS;. The registry submission is as follows:</p>
<code><![CDATA[
<transport>
<name>http-upload</name>
<desc>
A method for negotiating data exchange via uploading to HTTP URIs.
</desc>
<type>streaming</type>
<doc>XEP-XXXX</doc>
</transport>]]></code>
</section2>
</section1>
<section1 topic='XML Schema' anchor='schema'>
<section2 topic='urn:xmpp:jingle:transports:http:0'>
<code><![CDATA[
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:xmpp:jingle:transports:http:0'
xmlns='urn:xmpp:jingle:transports:http:0'
elementFormDefault='qualified'>
<xs:element name='transport'>
<xs:complexType>
<xs:all minOccurs='0'>
<xs:element name='candidate' type='httpSlotType' maxOccurs='unbounded' />
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name='httpSlotType'>
<xs:all minOccurs='0'>
<xs:element ref='header' maxOccurs='unbounded' />
</xs:all>
<xs:attribute name='uri' type='xs:anyURI' use='required' />
</xs:complexType>
<xs:element name='header'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='name' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>]]></code>
</section2>
<section2 topic='urn:xmpp:jingle:transports:http:upload:0'>
<code><![CDATA[
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:xmpp:jingle:transports:http:upload:0'
xmlns='urn:xmpp:jingle:transports:http:upload:0'
elementFormDefault='qualified'>
<xs:element name='transport'>
<xs:complexType>
<xs:all minOccurs='0'>
<xs:element name='candidate' type='httpSlotType' maxOccurs='unbounded' />
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name='httpSlotType'>
<xs:all minOccurs='0'>
<xs:element ref='header' maxOccurs='unbounded' />
</xs:all>
<xs:attribute name='uri' type='xs:anyURI' use='required' />
</xs:complexType>
<xs:element name='header'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='name' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>]]></code>
</section2>
<section2 topic='urn:xmpp:jingle:transports:http:info:0' anchor='schema-http0info'>
<code><![CDATA[
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:xmpp:jingle:tranports:http:info:0'
xmlns='urn:xmpp:jingle:transports:http:info:0'
elementFormDefault='qualified'>
<xs:element name='uploaded' type='contentSpecificType'/>
<xs:complexType name='contentSpecificType'>
<xs:simpleContent>
<xs:extension base='empty'>
<xs:attribute name='creator' use='required'>
<xs:simpleType>
<xs:restriction base='xs:NCName'>
<xs:enumeration value='initiator'/>
<xs:enumeration value='responder'/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name='name'
type='xs:string'
use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>]]></code>
</section2>
</section1>
</xep>

114
inbox/message-deletion.xml Normal file
View File

@ -0,0 +1,114 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Message Deletion</title>
<abstract>This specification defines a method for indicating that a message should be removed.</abstract>
&LEGALNOTICE;
<number>XXXX</number>
<status>Experimental</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>message-delete</shortname>
&lance;
<revision>
<version>0.0.1</version>
<date>2015-07-07</date>
<initials>ljts</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>Occasionally, a &xep0045; room moderator or admin might wish to remove certain chat messages from the room history as part of an effort to address and remedy issues such as message spam, indecent language for the venue, exposing private third-party personal information, etc. However, as with any content moderation tool, the removal request can <strong>only be considered as a hint</strong> and by itself can not prevent or undo any potential damage caused by the offending message, as clients which don't support message deletion are not obligated to enforce the deletion request and people could have seen or copied the message content already.</p>
</section1>
<section1 topic='Discovering support' anchor='disco'>
<p>If a client or service implements message deletion, it MUST specify the 'urn:xmpp:message-delete:0' feature in its service discovery information features as specified in &xep0030; and the Entity Capabilities profile specified in &xep0115;.</p>
<example caption='Client requests information about a chat partner&apos;s client'><![CDATA[
<iq type='get'
from='romeo@montague.net/orchard'
id='info1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>]]></example>
<example caption='Partner&apos;s client advertises support for removal'><![CDATA[
<iq type='get'
to='romeo@montague.net/home'
from='montague.net'
id='info1'>
<query xmlns='http://jabber.org/protocol/disco#info'>
...
<feature var='urn:xmpp:message-delete:0'/>
...
</query>
</iq>]]></example>
</section1>
<section1 topic='Use Case' anchor='usecase'>
<p>When a user indicates to the client that a sent message (or a received message for MUC room moderators) is meant to be deleted, the client will send a new message containing a &lt;remove /&gt; element with the "urn:xmpp:message-delete:0" namespace, with an id attribute set to the id of the message to be removed.</p>
<example caption='User sends a message with a mistake in'><![CDATA[
<message to='room@muc.example.com' id='bad1'>
<body>This message contained information not meant for this room.</body>
</message>]]></example>
<example caption='User inidcates that the message should be removed'><![CDATA[
<message to='room@muc.example.com' id='remove1'>
<remove id='bad1' xmlns='urn:xmpp:message-delete:0'/>
</message>]]></example>
</section1>
<section1 topic='Business Rules' anchor='rules'>
<p>A receiving client can choose to remove the indicated message from whatever display is used for messages, from any stored history, or choose to display the fact that a message has been removed in another way.</p>
<p>A MUC or other service that supports message removal SHOULD prevent further distribution of the message by the service (e.g., by not replaying the message to new occupants joining the room, or omitting the message from history archive requests where possible).</p>
<p>A client MAY inform the user that a no-longer displayed message did previously exist and has been removed.</p>
<p>Clients and services MUST set the 'id' attribute on messages if they allow for message deletion.</p>
<p>The Sender MUST NOT send a removal request for a message with non-messaging payloads. For example, a sender MUST NOT send a removal for a roster item exchange request or a file transfer part.</p>
<p>A removal MUST only be processed when both the original message and removal request are received from the same full-JID (or from a JID of an appropriate admin or moderator in the case of a MUC room.)</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>There can never be a guarantee that a removed message was never seen or otherwise distributed, and it is encouraged for clients and services when possible to inform users that no such guarantee exists.</p>
<p>When used in a &xep0045; context, removals send by non-moderators must not be allowed (by the receiver) for messages received before the sender joined the room - particularly a full JID leaving the room then rejoining and removing a message SHOULD be disallowed, as the entity behind the full JID in the MUC may have changed.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>None.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='ns'>
<p>The &REGISTRAR; includes 'urn:xmpp:message-delete:0' in its registry of protocol namespaces (see &NAMESPACES;).</p>
<ul>
<li>urn:xmpp:message-delete:0</li>
</ul>
</section2>
<section2 topic='Protocol Versioning' anchor='registrar-versioning'>
&NSVER;
</section2>
</section1>
<section1 topic='XML Schema' anchor='schema'>
<code><![CDATA[
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:xmpp:message-delete:0'
xmlns='urn:xmpp:message-delete:0'
elementFormDefault='qualified'>
<xs:element name='remove'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='id' type='xs:string' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
]]></code>
</section1>
</xep>

View File

@ -0,0 +1,182 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>OMEMO Encrypted Jingle File Transfer</title>
<abstract>This specification defines a Jingle application for transfering encrypted files from one entity to another. The protocol is based on the regular Jingle File Transfer specification and diverges from that only in the description of the file.</abstract>
<legal>
<copyright>This XMPP Extension Protocol is copyright (c) 1999 - 2014 by the XMPP Standards Foundation (XSF).</copyright>
<permissions>Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the &quot;Specification&quot;), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.</permissions>
<warranty>## NOTE WELL: This Specification is provided on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the XMPP Standards Foundation or the authors of this Specification be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification. ##</warranty>
<liability>In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising out of the use or inability to use the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.</liability>
<conformance>This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which may be found at &lt;<link url='http://xmpp.org/extensions/ipr-policy.shtml'>http://xmpp.org/extensions/ipr-policy.shtml</link>&gt; or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).</conformance>
</legal>
<number>xxxx</number>
<status>ProtoXEP</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>XEP-0001</spec>
<spec>Etc.</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
<author>
<firstname>Daniel</firstname>
<surname>Gultsch</surname>
<email>daniel@gultsch.de</email>
<jid>daniel@gultsch.de</jid>
</author>
<revision>
<version>0.0.1</version>
<date>2015-09-02</date>
<initials>dg</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>&xep0234; describes a very flexible and powerful method for peer-to-peer file transfer with interchangable transports. Unfortunatly only some of those transports can by encrypted (e.g. &xep0261;) and none integrate into existing end-to-end encryption schemes. This specification defines an approach to encrypt the actual file before transferring it by using the OMEMO encryption. Note that the encryption can and should happen on the fly.</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<ul>
<li>Keep the protocol flow as close to Jingle File Transfer as possible and only change the file description</li>
<li>Keep the required changes for a client that already supports Jingle File Transfer and the OMEMO encryption to a minimum</li>
</ul>
</section1>
<section1 topic='Use Cases' anchor='usecases'>
<p>Remeo and Juliet are already engaged in a private, OMEMO encrypted conversation and want to negotiate a file transfer. The session-initiate stanza of an OMEMO encrypted file tranfer differs from the session-initiate of a regular Jingle File Transfer in that the 'file' element is wrapped in an 'encrypted' element. This reuses the KeyTransportElement from the OMEMO specification.</p>
<example caption="Initiator sends session-initiate"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='nzu25s8'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='851ba2'>
<content creator='initiator' name='a-file-offer'>
<description xmlns='urn:xmpp:jingle:apps:encrypted:file-transfer:0'>
<encrypted xmlns='urn:xmpp:omemo:0'>
<header sid='27183'>
<key rid='31415'>BASE64ENCODED...</key>
<key rid='12321'>BASE64ENCODED...</key>
<iv>BASE64ENCODED...</iv>
</header>
<file>
<date>2015-08-30T23:24:05Z</date>
<desc>This is a test. If this were a real file...</desc>
<media-type>image/png</media-type>
<name>omemo.png</name>
<range/>
<size>51158</size>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'/>
</file>
</encrypted>
</description>
<transport xmlns='urn:xmpp:jingle:transports:s5b:1'
mode='tcp'
sid='vj3hs98y'>
<candidate cid='hft54dqy'
host='192.168.4.1'
jid='romeo@montague.lit/orchard'
port='5086'
priority='8257636'
type='direct'/>
<candidate cid='hutr46fe'
host='24.24.24.1'
jid='romeo@montague.lit/orchard'
port='5087'
priority='8258636'
type='direct'/>
</transport>
</content>
</jingle>
</iq>
]]></example>
<p>The rest of the negotiation is analogous to a regular file transfer. The file is then encrypted and decrypted respectively using the key/IV pair extracted from the encryption header in AES-GCM. The crypto operation SHOULD happen on the fly.</p>
</section1>
<section1 topic='Communicating the Checksum or Hashing Algorithm' anchor='hash'>
<p>Even though AES-GCM comes with build-in integrity protection the hosting entity can—at any time during the lifetime of the session—communicate the checksum of the encrypted file.</p>
<example caption="Initiator sends checksum in session-info"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='kqh401b5'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-info'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<checksum xmlns='urn:xmpp:jingle:apps:encrypted:file-transfer:0'>
<file>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>
</file>
</checksum>
</jingle>
</iq>
]]></example>
</section1>
<section1 topic='Business Rules' anchor='rules'>
<ul>
<li>AES-GCM being a block cipher will influence the file size. The file size reported in the session intilization MUST be the encrypted one.</li>
<li>The file hash MUST be the hash of encrypted file.</li>
<li>An encryption header MUST only be used for one session. However when doing a rangend tranfer on a previously aborted file the key/IV pair MUST be reused and packed into a new header to keep the integrity of the file.</li>
</ul>
</section1>
<section1 topic='Determining Support' anchor='support'>
<p>To advertise its support for the OMEMO Encrypted Jingle File Transfer, when replying to service discovery information ("disco#info") requests an entity MUST return URNs for any version of this protocol that the entity supports -- e.g., 'urn:xmpp:jingle:apps:encrypted:file-transfer:0' for this version &VNOTE;.</p>
<example caption="Service discovery information request"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='uw72g176'
to='juliet@capulet.lit/balcony'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<example caption="Service discovery information response"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='uw72g176'
to='romeo@montague.lit/orchard'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<feature var='urn:xmpp:jingle:1'/>
<feature var='urn:xmpp:jingle:apps:encrypted:file-transfer:0'/>
<feature var='urn:xmpp:jingle:apps:file-transfer:4'/>
<feature var='urn:xmpp:jingle:transports:s5b:1'/>
<feature var='urn:xmpp:jingle:transports:ibb:1'/>
</query>
</iq>
]]></example>
<p>In order for an application to determine whether an entity supports this protocol, where possible it SHOULD use the dynamic, presence-based profile of service discovery defined in &xep0115;. However, if an application has not received entity capabilities information from an entity, it SHOULD use explicit service discovery instead.</p>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
<p>Since the OMEMO Encryption does not provide a direct relation between resources and Device IDs the initiating entity might not the Device ID of the resource it is creating a session with. Thus it MAY include a key for every trusted device of the foreign entity. However it SHOULD omit the keys for its own devices.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<ul>
<li>Being built upon both Jingle File Transfer and OMEMO encryption, the same security considerations apply.</li>
<li>Only the raw file is being encrypted. The encryption does not apply for the meta data sent with the session initialization including the content-type and the description</li>
</ul>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with the Internet Assigned Numbers Authority (IANA).</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>This specification defines the following XML namespace:</p>
<ul>
<li>urn:xmpp:jingle:apps:encrypted:file-transfer:0</li>
</ul>
<p>Upon advancement of this specification from a status of Experimental to a status of Draft, the &REGISTRAR; shall add the foregoing namespace to the registry located at &NAMESPACES;, as described in Section 4 of &xep0053;.</p>
</section2>
</section1>
<section1 topic='XML Schema' anchor='schema'>
<p>tbd</p>
</section1>
</xep>

299
inbox/omemo.xml Normal file
View File

@ -0,0 +1,299 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>OMEMO Encryption</title>
<abstract>This specification defines a protocol for end-to-end encryption in one-on-one chats that may have multiple clients per account.</abstract>
<legal>
<copyright>This XMPP Extension Protocol is copyright (c) 1999 - 2014 by the XMPP Standards Foundation (XSF).</copyright>
<permissions>Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the &quot;Specification&quot;), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.</permissions>
<warranty>## NOTE WELL: This Specification is provided on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the XMPP Standards Foundation or the authors of this Specification be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification. ##</warranty>
<liability>In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising out of the use or inability to use the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.</liability>
<conformance>This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which may be found at &lt;<link url='http://xmpp.org/extensions/ipr-policy.shtml'>http://xmpp.org/extensions/ipr-policy.shtml</link>&gt; or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).</conformance>
</legal>
<number>xxxx</number>
<status>ProtoXEP</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>XEP-0163</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
<author>
<firstname>Andreas</firstname>
<surname>Straub</surname>
<email>andy@strb.org</email>
<jid>andy@strb.org</jid>
</author>
<revision>
<version>0.0.1</version>
<date>2015-10-25</date>
<initials>as</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<section2 topic='Motivation' anchor='intro-motivation'>
<p>There are two main end-to-end encryption schemes in common use in the XMPP ecosystem, Off-the-Record (OTR) messaging (&xep0364;) and OpenPGP (&xep0027;). OTR has significant usability drawbacks for inter-client mobility. As OTR sessions exist between exactly two clients, the chat history will not be synchronized across other clients of the involved parties. Furthermore, OTR chats are only possible if both participants are currently online, due to how the rolling key agreement scheme of OTR works. OpenPGP, while not suffering from these mobility issues, does not provide any kind of forward secrecy and is vulnerable to replay attacks. Additionally, PGP over XMPP uses a custom wireformat which is defined by convention rather than standardization, and involves quite a bit of external complexity.</p>
<p>This XEP defines a protocol that leverages axolotl encryption to provide multi-end to multi-end encryption, allowing messages to be synchronized securely across multiple clients, even if some of them are offline.</p>
</section2>
<section2 topic='Overview' anchor='intro-overview'>
<p>The general idea behind this protocol is to maintain separate, long-standing axolotl-encrypted sessions with each device of each contact (as well as with each of our other devices), which are used as secure key transport channels. In this scheme, each message is encrypted with a fresh, randomly generated encryption key. An encrypted header is added to the message for each device that is supposed to receive it. These headers simply contain the key that the payload message is encrypted with, and they are seperately encrypted using the session corresponding to the counterpart device. The encrypted payload is sent together with the headers as a &lt;message&gt; stanza. Individual recipient devices can decrypt the header item intended for them, and use the contained payload key to decrypt the payload message.</p>
<p>As the encrypted payload is common to all recipients, it only has to be included once, reducing overhead. Furthermore, axolotl's transparent handling of messages that were lost or received out of order, as well as those sent while the recipient was offline, is maintained by this protocol. As a result, in combination with &xep0280; and &xep0313;, the desired property of inter-client history synchronization is achieved.</p>
<p>OMEMO version 0 uses v3 messages of the axolotl protocol. Instead of an axolotl key server, PEP (&xep0163;) is used to publish key data. </p>
</section2>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<ul>
<li>Provide forward secrecy</li>
<li>Ensure chat messages can be deciphered by all (capable) clients of both parties</li>
<li>Be usable regardless of the participants' online statuses</li>
<li>Provide a method to exchange auxilliary keying material. This could for example be used to secure encrypted file transfers.</li>
</ul>
</section1>
<section1 topic='Glossary' anchor='glossary'>
<section2 topic='General Terms' anchor='glossary-general'>
<dl>
<di><dt>Device</dt><dd>A communication end point, i.e. a specific client instance</dd></di>
<di><dt>OMEMO element</dt><dd>An &lt;encrypted&gt; element in the urn:xmpp:omemo:0 namespace. Can be either MessageElement or a KeyTransportElement</dd></di>
<di><dt>MessageElement</dt><dd>An OMEMO element that contains a chat message. Its &lt;payload&gt;, when decrypted, corresponds to a &lt;message&gt;'s &lt;body&gt;.</dd></di>
<di><dt>KeyTransportElement</dt><dd>An OMEMO element that does not have a &lt;payload&gt;. It contains a fresh encryption key, which can be used for purposes external to this XEP.</dd></di>
<di><dt>Bundle</dt><dd>A collection of publicly accessible data that can be used to build a session with a device, namely its public IdentityKey, a signed PreKey with corresponding signature, and a list of (single use) PreKeys.</dd></di>
<di><dt>rid</dt><dd>The device id of the intended recipient of the containing &lt;key&gt;</dd></di>
<di><dt>sid</dt><dd>The device id of the sender of the containing OMEMO element</dd></di>
</dl>
</section2>
<section2 topic='Axolotl-specific' anchor='glossary-axolotl'>
<dl>
<di><dt>IdentityKey</dt><dd>Per-device public/private key pair used to authenticate communications</dd></di>
<di><dt>PreKey</dt><dd>A Diffie-Hellman public key, published in bulk and ahead of time</dd></di>
<di><dt>PreKeyWhisperMessage</dt><dd>An encrypted message that includes the initial key exchange. This is used to transparently build sessions with the first exchanged message.</dd></di>
<di><dt>WhisperMessage</dt><dd>An encrypted message</dd></di>
</dl>
</section2>
</section1>
<section1 topic='Use Cases' anchor='usecases'>
<section2 topic='Setup' anchor='usecases-setup'>
<p>The first thing that needs to happen if a client wants to start using OMEMO is they need to generate an IdentityKey and a Device ID. The IdentityKey is a <a href='http://cr.yp.to/ecdh/curve25519-20060209.pdf'>Curve25519</a> public/private Key pair. The Device ID is a randomly generated integer between 1 and 2^31 - 1. </p>
</section2>
<section2 topic='Discovering peer support' anchor='usecases-discovering'>
<p>In order to determine whether a given contact has devices that support OMEMO, the devicelist node in PEP is consulted. Devices MUST subscribe to 'urn:xmpp:omemo:0:devicelist' via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the devicelist.</p>
<example caption='Devicelist update received by subscribed clients'><![CDATA[
<message from='juliet@capulet.lit'
to='romeo@montague.lit'
type='headline'
id='update_01'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='urn:xmpp:omemo:0:devicelist'>
<item>
<list xmlns='urn:xmpp:omemo:0'>
<device id='12345' />
<device id='4223' />
</list>
</item>
</items>
</event>
</message>]]></example>
</section2>
<section2 topic='Announcing support' anchor='usecases-announcing'>
<p>In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device ID to the devicelist PEP node. </p>
<example caption='Adding the own device ID to the list'><![CDATA[
<iq from='juliet@capulet.lit' type='set' id='announce1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='urn:xmpp:omemo:0:devicelist'>
<item>
<list xmlns='urn:xmpp:omemo:0'>
<device id='12345' />
<device id='4223' />
<device id='31415' />
</list>
</item>
</publish>
</pubsub>
</iq>]]></example>
<p>This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.</p>
<p>Furthermore, a device MUST announce it's IdentityKey, a signed PreKey, and a list of PreKeys in a separate, per-device PEP node. The list SHOULD contain 100 PreKeys, but MUST contain no less than 20.</p>
<example caption='Announcing bundle information'><![CDATA[
<iq from='juliet@capulet.lit' type='set' id='announce2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='urn:xmpp:omemo:0:bundles:31415'>
<item>
<bundle xmlns='urn:xmpp:omemo:0'>
<signedPreKeyPublic signedPreKeyId='1'>
BASE64ENCODED...
</signedPreKeyPublic>
<signedPreKeySignature>
BASE64ENCODED...
</signedPreKeySignature>
<identityKey>
BASE64ENCODED...
</identityKey>
<prekeys>
<preKeyPublic preKeyId='1'>
BASE64ENCODED...
</preKeyPublic>
<preKeyPublic preKeyId='2'>
BASE64ENCODED...
</preKeyPublic>
<preKeyPublic preKeyId='3'>
BASE64ENCODED...
</preKeyPublic>
<!-- ... -->
</prekeys>
</bundle>
</item>
</publish>
</pubsub>
</iq>]]></example>
</section2>
<section2 topic='Building a session' anchor='usecases-building'>
<p>In order to build a session with a device, their bundle information is fetched.</p>
<example caption="Fetching a device's bundle information"><![CDATA[
<iq type='get'
from='romeo@montague.lit'
to='juliet@capulet.lit'
id='fetch1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<items node='urn:xmpp:omemo:0:bundles:31415'/>
</pubsub>
</iq>]]></example>
<p>A random preKeyPublic entry is selected, and used to build an axolotl session.</p>
</section2>
<section2 topic='Sending a message' anchor='usecases-messagesend'>
<p>In order to send a chat message, its &lt;body&gt; first has to be encrypted. The client MUST use fresh, randomly generated key/IV pairs with AES-128 in Galois/Counter Mode (GCM). For each intended recipient device, i.e. both own devices as well as devices associated with the contact, this key is encrypted using the corresponding long-standing axolotl session. Each encrypted payload key is tagged with the recipient device's ID. This is all serialized into a MessageElement, which is transmitted in a &lt;message&gt; as follows:</p>
<example caption="Sending a message"><![CDATA[
<message to='juliet@capulet.lit' from='romeo@montague.lit' id='send1'>
<encrypted xmlns='urn:xmpp:omemo:0'>
<header sid='27183'>
<key rid='31415'>BASE64ENCODED...</key>
<key rid='12321'>BASE64ENCODED...</key>
<!-- ... -->
<iv>BASE64ENCODED...</iv>
</header>
<payload>BASE64ENCODED</payload>
</encrypted>
<store xmlns='urn:xmpp:hints'/>
</message>]]></example>
</section2>
<section2 topic='Sending a key' anchor='usecases-keysend'>
<p>The client may wish to transmit keying material to the contact. This first has to be generated. The client MUST generate a fresh, randomly generated key/IV pair. For each intended recipient device, i.e. both own devices as well as devices associated with the contact, this key is encrypted using the corresponding long-standing axolotl session. Each encrypted payload key is tagged with the recipient device's ID. This is all serialized into a KeyTransportElement, omitting the &lt;payload&gt; as follows:</p>
<example caption="Sending a key"><![CDATA[
<encrypted xmlns='urn:xmpp:omemo:0'>
<header sid='27183'>
<key rid='31415'>BASE64ENCODED...</key>
<key rid='12321'>BASE64ENCODED...</key>
<!-- ... -->
<iv>BASE64ENCODED...</iv>
</header>
</encrypted>]]></example>
<p>This KeyTransportElement can then be sent over any applicable transport mechanism.</p>
</section2>
<section2 topic='Receiving a message' anchor='usecases-receiving'>
<p>When an OMEMO element is received, the client MUST check whether there is a &lt;key&gt; element with an rid attribute matching its own device ID. If this is not the case, the element MUST be silently discarded. If such an element exists, the client checks whether the element's contents are a PreKeyWhisperMessage.</p>
<p>If this is the case, a new session is built from this received element. The client SHOULD then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST delete the private key belonging to the PreKey after use.</p>
<p>If the element's contents are a WhisperMessage, and the client has a session with the sender's device, it tries to decrypt the WhisperMessage using this session. If the decryption fails or if the element's contents are not a WhisperMessage either, the OMEMO element MUST be silently discarded.</p>
<p>If the OMEMO element contains a &lt;payload&gt;, it is an OMEMO message element. The client tries to decrypt the base 64 encoded contents using the key extracted from the &lt;key&gt; element. If the decryption fails, the client MUST silently discard the OMEMO message. If it succeeds, the decrypted contents are treated as the &lt;body&gt; of the received message.</p>
<p>If the OMEMO element does not contain a &lt;payload&gt;, the client has received a KeyTransportElement. The key extracted from the &lt;key&gt; element can then be used for other purposes (e.g. encrypted file transfer).</p>
</section2>
</section1>
<section1 topic='Business Rules' anchor='rules'>
<p>Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.</p>
<p>Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial PreKeyWhisperMessage later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message. </p>
<p>As there are no explicit error messages in this protocol, if a client does receive a PreKeyWhisperMessage using an invalid PreKey, they SHOULD respond with a KeyTransportElement, sent in a &lt;message&gt; using a PreKeyWhisperMessage. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.</p>
<p>If a PreKeyWhisperMessage is received as part of a &xep0313; catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a KeyTransportMessage using a PreKeyWhisperMessage before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.</p>
<p>As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; &lt;store /&gt; hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a &lt;body /&gt;</p>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
<p>For details on axoltol, see the <a href='https://github.com/trevp/axolotl/wiki'>specification</a> and <a href='https://github.com/WhisperSystems/libaxolotl-java'>reference implementation.</a></p>
<p>The axolotl library's reference implementation (and presumably its ports to various other platforms) uses a trust model that doesn't work very well with OMEMO. For this reason it may be desirable to have the library consider all keys trusted, effectively disabling its trust management. This makes it necessary to implement trust handling oneself.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>Clients MUST NOT use a newly built session to transmit data without user intervention. If a client were to opportunistically start using sessions for sending without asking the user whether to trust a device first, an attacker could publish a fake device for this user, which would then receive copies of all messages sent by/to this user. A client MAY use such "not (yet) trusted" sessions for decryption of received messages, but in that case it SHOULD indicate the untrusted nature of such messages to the user.</p>
<p>When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user.</p>
<p>While it is RECOMMENDED that clients postpone private key deletion until after MAM catch-up and this standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to <note>Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158.</note>.</p>
<p>In order to be able to handle out-of-order messages, the axolotl stack has to cache the keys belonging to "skipped" messages that have not been seen yet. It is up to the implementor to decide how long and how many of such keys to keep around.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with the Internet Assigned Numbers Authority (IANA). </p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='namespaces'>
<p>This specification defines the following XMPP namespaces:</p>
<ul>
<li>urn:xmpp:omemo:0</li>
</ul>
<p>The &REGISTRAR; shall include the foregoing namespace in its registry at &NAMESPACES;, as goverened by &xep0053;.</p>
</section2>
<section2 topic='Protocol Versioning' anchor='versioning'>
&NSVER;
</section2>
</section1>
<section1 topic='XML Schema' anchor='schema'>
<code><![CDATA[
<xml version="1.0" encoding="utf8">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:xmpp:omemo:0"
xmlns="urn:xmpp:omemo:0">
<xs:element name="encrypted">
<xs:element name="header">
<xs:attribute name="sid" type="xs:integer"/>
<xs:complexType>
<xs:sequence>
<xs:element name="key" type="xs:base64Binary" maxOccurs="unbounded">
<xs:attribute name="rid" type="xs:integer"/>
</xs:element>
<xs:element name="iv" type="xs:base64Binary"/>
</xs:complexType>
</xs:element>
<xs:element name="payload" type="xs:base64Binary" minOccurs="0"/>
</xs:element>
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element name="device" maxOccurs="unbounded">
<xs:attribute name="id" type="integer"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="bundle">
<xs:complexType>
<xs:sequence>
<xs:element name="signedPreKeyPublic" type="base64Binary">
<xs:attribute name="id" type="integer"/>
</xs:element>
<xs:element name="signedPreKeySignature" type="base64Binary"/>
<xs:element name="identityKey" type="base64Binary"/>
<xs:element name="prekeys">
<xs:complexType>
<xs:sequence>
<xs:element name="preKeyPublic" type="base64Binary" maxOccurs="unbounded">
<xs:attribute name="id" type="integer"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
]]></code>
</section1>
<section1 topic='Acknowledgements' anchor='ack'>
<p>Big thanks to Daniel Gultsch for mentoring me during the development of this protocol. Thanks to Thijs Alkemade and Cornelius Aschermann for talking through some of the finer points of the protocol with me. And lastly I would also like to thank Sam Whited, Holger Weiss, and Florian Schmaus for their input on the standard.</p>
</section1>
</xep>

112
inbox/otrdisco.xml Normal file
View File

@ -0,0 +1,112 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>OTR Discovery</title>
<abstract>
This document provides a mechanism by which OTR encryption support can be
discovered in XMPP, without relying on OTRs protocol agnostic discovery
mechanism.
</abstract>
&LEGALNOTICE;
<number>xxxx</number>
<status>ProtoXEP</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>XEP-0030</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
<author>
<firstname>Sam</firstname>
<surname>Whited</surname>
<email>sam@samwhited.com</email>
<jid>sam@samwhited.com</jid>
</author>
<revision>
<version>0.0.1</version>
<date>2015-08-29</date>
<initials>ssw</initials>
<remark><p>Initial draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>
The Off-the-Record messaging protocol (OTR) is widely layered on top of
XMPP to provide end-to-end encryption. Current use of the protocol is
described in &xep0364;. OTR provides its own discovery mechanism in which
it sends messages with special whitespace characters to indicate support.
While this works when initializing a session, there is no way to query a
client for support and to know in advance that a particular version of
OTR is supported. This specification aims to solve that by providing an
in-band mechanism for discovering OTR support in XMPP.
</p>
<p>
It should be noted that newer, more secure encryption protocols exist for
XMPP, and that new implementations of OTR are discouraged. This protocol
is primarily intended to solve issues with existing implementations of
OTR.
</p>
</section1>
<section1 topic='Discovering support' anchor='disco'>
<p>
If an entity supports OTR it MUST advertise the fact by returning a
feature of 'urn:xmpp:otr:0' &VNOTE; in response to a &xep0030;
information request. This indicates support for OTRv3 as defined by
<i><link url='https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html'>
Off-the-Record Messaging Protocol version 3
</link></i>
<note>
(Accessed 2015-08-30). "Off-the-Record Messaging Protocol version 3"
&lt;<link url='https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html'>
https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html
</link>&gt;
</note>.
<example caption='Disco response'><![CDATA[
<feature var='urn:xmpp:otr:0' />
]]></example>
</p>
<p>
If older versions of OTR are required, they may be discovered out of band
using OTRs built in mechanism which is beyond the scope of this document.
</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>
Because OTR support is advertised outside of any end-to-end encrypted
stream, it may be subject to downgrade attacks (eg. the server operator
may remove OTR from the features list).
</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>
This document requires no interaction with the Internet Assigned Numbers
Authority (IANA).
</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<p>This specification defines the following XML namespaces:</p>
<ul>
<li>urn:xmpp:otr:0</li>
</ul>
<p>
The &REGISTRAR; shall include the foregoing namespaces in its disco
features registry as defined in &xep0030;.
<code caption='Registry Submission'><![CDATA[
<var>
<name>urn:xmpp:otr:0</name>
<desc>Indicates support for Off-the-Record Messaging (OTR) version 3</desc>
<doc>XEP-xxxx</doc>
</var>
]]></code>
</p>
</section1>
</xep>

27
prettify.css Executable file
View File

@ -0,0 +1,27 @@
/* Pretty printing styles. Used with prettify.js. */
.str { color: #080; }
.kwd { color: #008; }
.com { color: #800; }
.typ { color: #606; }
.lit { color: #066; }
.pun { color: #660; }
.pln { color: #000; }
.tag { color: #008; }
.atn { color: #606; }
.atv { color: #080; }
.dec { color: #606; }
pre.prettyprint { padding: 2px; border: 1px solid #888; }
@media print {
.str { color: #060; }
.kwd { color: #006; font-weight: bold; }
.com { color: #600; font-style: italic; }
.typ { color: #404; font-weight: bold; }
.lit { color: #044; }
.pun { color: #440; }
.pln { color: #000; }
.tag { color: #006; font-weight: bold; }
.atn { color: #404; }
.atv { color: #060; }
}

33
prettify.js Executable file
View File

@ -0,0 +1,33 @@
(function(){
var o=true,r=null,z=false;window.PR_SHOULD_USE_CONTINUATION=o;window.PR_TAB_WIDTH=8;window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void 0;window._pr_isIE6=function(){var N=navigator&&navigator.userAgent&&/\bMSIE 6\./.test(navigator.userAgent);window._pr_isIE6=function(){return N};return N};
var aa="!",ba="!=",ca="!==",F="#",da="%",ea="%=",G="&",fa="&&",ja="&&=",ka="&=",H="(",la="*",ma="*=",na="+=",oa=",",pa="-=",qa="->",ra="/",sa="/=",ta=":",ua="::",va=";",I="<",wa="<<",xa="<<=",ya="<=",za="=",Aa="==",Ba="===",J=">",Ca=">=",Da=">>",Ea=">>=",Fa=">>>",Ga=">>>=",Ha="?",Ia="@",L="[",M="^",Ta="^=",Ua="^^",Va="^^=",Wa="{",O="|",Xa="|=",Ya="||",Za="||=",$a="~",ab="break",bb="case",cb="continue",db="delete",eb="do",fb="else",gb="finally",hb="instanceof",ib="return",jb="throw",kb="try",lb="typeof",
mb="(?:^^|[+-]",nb="\\$1",ob=")\\s*",pb="&amp;",qb="&lt;",rb="&gt;",sb="&quot;",tb="&#",ub="x",vb="'",wb='"',xb=" ",yb="XMP",zb="</",Ab='="',P="",Q="\\",Bb="b",Cb="t",Db="n",Eb="v",Fb="f",Gb="r",Hb="u",Ib="0",Jb="1",Kb="2",Lb="3",Mb="4",Nb="5",Ob="6",Pb="7",Qb="\\x0",Rb="\\x",Sb="-",Tb="]",Ub="\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]",R="g",Vb="\\B",Wb="\\b",Xb="\\D",Yb="\\d",Zb="\\S",$b="\\s",ac="\\W",bc="\\w",cc="(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)",
dc="(?:",ec=")",fc="gi",gc="PRE",hc='<!DOCTYPE foo PUBLIC "foo bar">\n<foo />',ic="\t",jc="\n",kc="[^<]+|<!--[\\s\\S]*?--\>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|</?[a-zA-Z][^>]*>|<",lc="nocode",mc=' $1="$2$3$4"',S="pln",nc="string",T="lang-",oc="src",U="str",pc="'\"",qc="'\"`",rc="\"'",V="com",sc="lang-regex",tc="(/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/)",uc="kwd",vc="^(?:",wc=")\\b",xc=" \r\n\t\u00a0",yc="lit",zc="typ",Ac="0123456789",Y="pun",Bc="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename typeof using virtual wchar_t where break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try debugger eval export function get null set undefined var with Infinity NaN caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END break continue do else for if return while case done elif esac eval fi function in local set then until ",
Cc="</span>",Dc='<span class="',Ec='">',Fc="$1&nbsp;",Gc="&nbsp;<br />",Hc="<br />",Ic="console",Jc="cannot override language handler %s",Kc="default-markup",Lc="default-code",Mc="dec",Z="lang-js",$="lang-css",Nc="lang-in.tag",Oc="htm",Pc="html",Qc="mxml",Rc="xhtml",Sc="xml",Tc="xsl",Uc=" \t\r\n",Vc="atv",Wc="tag",Xc="atn",Yc="lang-uq.val",Zc="in.tag",$c="uq.val",ad="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename typeof using virtual wchar_t where ",
bd="c",cd="cc",dd="cpp",ed="cxx",fd="cyc",gd="m",hd="null true false",id="json",jd="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var ",
kd="cs",ld="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ",md="java",nd="break continue do else for if return while case done elif esac eval fi function in local set then until ",
od="bsh",pd="csh",qd="sh",rd="break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ",sd="cv",td="py",ud="caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ",vd="perl",wd="pl",xd="pm",yd="break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ",
zd="rb",Ad="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try debugger eval export function get null set undefined var with Infinity NaN ",Bd="js",Cd="regex",Dd="pre",Ed="code",Fd="xmp",Gd="prettyprint",Hd="class",Id="br",Jd="\r";
(function(){var N=function(){for(var a=[aa,ba,ca,F,da,ea,G,fa,ja,ka,H,la,ma,na,oa,pa,qa,ra,sa,ta,ua,va,I,wa,xa,ya,za,Aa,Ba,J,Ca,Da,Ea,Fa,Ga,Ha,Ia,L,M,Ta,Ua,Va,Wa,O,Xa,Ya,Za,$a,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb],b=mb,c=0;c<a.length;++c)b+=O+a[c].replace(/([^=<>:&a-z])/g,nb);b+=ob;return b}(),Ja=/&/g,Ka=/</g,La=/>/g,Kd=/\"/g;function Ld(a){return a.replace(Ja,pb).replace(Ka,qb).replace(La,rb).replace(Kd,sb)}function ga(a){return a.replace(Ja,pb).replace(Ka,qb).replace(La,rb)}var Md=/&lt;/g,Nd=/&gt;/g,
Od=/&apos;/g,Pd=/&quot;/g,Qd=/&amp;/g,Rd=/&nbsp;/g;function Sd(a){var b=a.indexOf(G);if(b<0)return a;for(--b;(b=a.indexOf(tb,b+1))>=0;){var c=a.indexOf(va,b);if(c>=0){var d=a.substring(b+3,c),g=10;if(d&&d.charAt(0)===ub){d=d.substring(1);g=16}var i=parseInt(d,g);isNaN(i)||(a=a.substring(0,b)+String.fromCharCode(i)+a.substring(c+1))}}return a.replace(Md,I).replace(Nd,J).replace(Od,vb).replace(Pd,wb).replace(Qd,G).replace(Rd,xb)}function Ma(a){return yb===a.tagName}function W(a,b){switch(a.nodeType){case 1:var c=
a.tagName.toLowerCase();b.push(I,c);for(var d=0;d<a.attributes.length;++d){var g=a.attributes[d];if(g.specified){b.push(xb);W(g,b)}}b.push(J);for(var i=a.firstChild;i;i=i.nextSibling)W(i,b);if(a.firstChild||!/^(?:br|link|img)$/.test(c))b.push(zb,c,J);break;case 2:b.push(a.name.toLowerCase(),Ab,Ld(a.value),wb);break;case 3:case 4:b.push(ga(a.nodeValue));break}}function Na(a){for(var b=0,c=z,d=z,g=0,i=a.length;g<i;++g){var m=a[g];if(m.ignoreCase)d=o;else if(/[a-z]/i.test(m.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,
P))){c=o;d=z;break}}function l(j){if(j.charAt(0)!==Q)return j.charCodeAt(0);switch(j.charAt(1)){case Bb:return 8;case Cb:return 9;case Db:return 10;case Eb:return 11;case Fb:return 12;case Gb:return 13;case Hb:case ub:return parseInt(j.substring(2),16)||j.charCodeAt(1);case Ib:case Jb:case Kb:case Lb:case Mb:case Nb:case Ob:case Pb:return parseInt(j.substring(1),8);default:return j.charCodeAt(1)}}function n(j){if(j<32)return(j<16?Qb:Rb)+j.toString(16);var f=String.fromCharCode(j);if(f===Q||f===Sb||
f===L||f===Tb)f=Q+f;return f}function q(j){for(var f=j.substring(1,j.length-1).match(new RegExp(Ub,R)),s=[],k=[],h=f[0]===M,e=h?1:0,p=f.length;e<p;++e){var t=f[e];switch(t){case Vb:case Wb:case Xb:case Yb:case Zb:case $b:case ac:case bc:s.push(t);continue}var u=l(t),x;if(e+2<p&&Sb===f[e+1]){x=l(f[e+2]);e+=2}else x=u;k.push([u,x]);if(!(x<65||u>122)){x<65||u>90||k.push([Math.max(65,u)|32,Math.min(x,90)|32]);x<97||u>122||k.push([Math.max(97,u)&-33,Math.min(x,122)&-33])}}k.sort(function(Oa,Pa){return Oa[0]-
Pa[0]||Pa[1]-Oa[1]});var B=[],E=[NaN,NaN];for(e=0;e<k.length;++e){var A=k[e];if(A[0]<=E[1]+1)E[1]=Math.max(E[1],A[1]);else B.push(E=A)}var D=[L];h&&D.push(M);D.push.apply(D,s);for(e=0;e<B.length;++e){A=B[e];D.push(n(A[0]));if(A[1]>A[0]){A[1]+1>A[0]&&D.push(Sb);D.push(n(A[1]))}}D.push(Tb);return D.join(P)}function v(j){var f=j.source.match(new RegExp(cc,R)),s=f.length,k=[],h,e=0;for(h=0;e<s;++e){var p=f[e];if(p===H)++h;else if(Q===p.charAt(0)){var t=+p.substring(1);if(t&&t<=h)k[t]=-1}}for(e=1;e<k.length;++e)if(-1===
k[e])k[e]=++b;for(h=e=0;e<s;++e){p=f[e];if(p===H){++h;if(k[h]===undefined)f[e]=dc}else if(Q===p.charAt(0))if((t=+p.substring(1))&&t<=h)f[e]=Q+k[h]}for(h=e=0;e<s;++e)if(M===f[e]&&M!==f[e+1])f[e]=P;if(j.ignoreCase&&c)for(e=0;e<s;++e){p=f[e];var u=p.charAt(0);if(p.length>=2&&u===L)f[e]=q(p);else if(u!==Q)f[e]=p.replace(/[a-zA-Z]/g,function(x){var B=x.charCodeAt(0);return L+String.fromCharCode(B&-33,B|32)+Tb})}return f.join(P)}var w=[];g=0;for(i=a.length;g<i;++g){m=a[g];if(m.global||m.multiline)throw new Error(P+
m);w.push(dc+v(m)+ec)}return new RegExp(w.join(O),d?fc:R)}var ha=r;function Td(a){if(r===ha){var b=document.createElement(gc);b.appendChild(document.createTextNode(hc));ha=!/</.test(b.innerHTML)}if(ha){var c=a.innerHTML;if(Ma(a))c=ga(c);return c}for(var d=[],g=a.firstChild;g;g=g.nextSibling)W(g,d);return d.join(P)}function Ud(a){var b=0;return function(c){for(var d=r,g=0,i=0,m=c.length;i<m;++i){var l=c.charAt(i);switch(l){case ic:d||(d=[]);d.push(c.substring(g,i));var n=a-b%a;for(b+=n;n>=0;n-=" ".length)d.push(" ".substring(0,
n));g=i+1;break;case jc:b=0;break;default:++b}}if(!d)return c;d.push(c.substring(g));return d.join(P)}}var Vd=new RegExp(kc,R),Wd=/^<\!--/,Xd=/^<\[CDATA\[/,Yd=/^<br\b/i,Qa=/^<(\/?)([a-zA-Z]+)/;function Zd(a){var b=a.match(Vd),c=[],d=0,g=[];if(b)for(var i=0,m=b.length;i<m;++i){var l=b[i];if(l.length>1&&l.charAt(0)===I){if(!Wd.test(l))if(Xd.test(l)){c.push(l.substring(9,l.length-3));d+=l.length-12}else if(Yd.test(l)){c.push(jc);++d}else if(l.indexOf(lc)>=0&&$d(l)){var n=l.match(Qa)[2],q=1,v;v=i+1;a:for(;v<
m;++v){var w=b[v].match(Qa);if(w&&w[2]===n)if(w[1]===ra){if(--q===0)break a}else++q}if(v<m){g.push(d,b.slice(i,v+1).join(P));i=v}else g.push(d,l)}else g.push(d,l)}else{var j=Sd(l);c.push(j);d+=j.length}}return{source:c.join(P),tags:g}}function $d(a){return!!a.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,mc).match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)}function ia(a,b,c,d){if(b){var g={source:b,b:a};c(g);d.push.apply(d,g.c)}}function K(a,b){var c={},d;(function(){for(var m=a.concat(b),
l=[],n={},q=0,v=m.length;q<v;++q){var w=m[q],j=w[3];if(j)for(var f=j.length;--f>=0;)c[j.charAt(f)]=w;var s=w[1],k=P+s;if(!n.hasOwnProperty(k)){l.push(s);n[k]=r}}l.push(/[\0-\uffff]/);d=Na(l)})();var g=b.length,i=function(m){for(var l=m.source,n=m.b,q=[n,S],v=0,w=l.match(d)||[],j={},f=0,s=w.length;f<s;++f){var k=w[f],h=j[k],e,p;if(typeof h===nc)p=z;else{var t=c[k.charAt(0)];if(t){e=k.match(t[1]);h=t[0]}else{for(var u=0;u<g;++u){t=b[u];if(e=k.match(t[1])){h=t[0];break}}e||(h=S)}if((p=h.length>=5&&T===
h.substring(0,5))&&!(e&&e[1])){p=z;h=oc}p||(j[k]=h)}var x=v;v+=k.length;if(p){var B=e[1],E=k.indexOf(B),A=E+B.length,D=h.substring(5);ia(n+x,k.substring(0,E),i,q);ia(n+x+E,B,Ra(D,B),q);ia(n+x+A,k.substring(A),i,q)}else q.push(n+x,h)}m.c=q};return i}function C(a){var b=[],c=[];if(a.tripleQuotedStrings)b.push([U,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,r,pc]);
else a.multiLineStrings?b.push([U,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,r,qc]):b.push([U,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,r,rc]);if(a.hashComments)a.cStyleComments?b.push([V,/^#(?:[^\r\n\/]|\/(?!\*)|\/\*[^\r\n]*?\*\/)*/,r,F]):b.push([V,/^#[^\r\n]*/,r,F]);if(a.cStyleComments){c.push([V,/^\/\/[^\r\n]*/,r]);c.push([V,/^\/\*[\s\S]*?(?:\*\/|$)/,r])}a.regexLiterals&&c.push([sc,new RegExp(M+N+tc)]);var d=
a.keywords.replace(/^\s+|\s+$/g,P);d.length&&c.push([uc,new RegExp(vc+d.replace(/\s+/g,O)+wc),r]);b.push([S,/^\s+/,r,xc]);c.push([yc,/^@[a-z_$][a-z_$@0-9]*/i,r,Ia],[zc,/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/,r],[S,/^[a-z_$][a-z_$@0-9]*/i,r],[yc,/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,r,Ac],[Y,/^.[^\s\w\.$@\'\"\`\/\#]*/,r]);return K(b,c)}var ae=C({keywords:Bc,hashComments:o,cStyleComments:o,multiLineStrings:o,regexLiterals:o});function be(a){var b=a.source,c=a.f,d=a.c,
g=[],i=0,m=r,l=r,n=0,q=0,v=Ud(window.PR_TAB_WIDTH),w=/([\r\n ]) /g,j=/(^| ) /gm,f=/\r\n?|\n/g,s=/[ \r\n]$/,k=o;function h(p){if(p>i){if(m&&m!==l){g.push(Cc);m=r}if(!m&&l){m=l;g.push(Dc,m,Ec)}var t=ga(v(b.substring(i,p))).replace(k?j:w,Fc);k=s.test(t);var u=window._pr_isIE6()?Gc:Hc;g.push(t.replace(f,u));i=p}}for(;1;){var e;if(e=n<c.length?q<d.length?c[n]<=d[q]:o:z){h(c[n]);if(m){g.push(Cc);m=r}g.push(c[n+1]);n+=2}else if(q<d.length){h(d[q]);l=d[q+1];q+=2}else break}h(b.length);m&&g.push(Cc);a.a=g.join(P)}
var X={};function y(a,b){for(var c=b.length;--c>=0;){var d=b[c];if(X.hasOwnProperty(d))Ic in window&&console.i(Jc,d);else X[d]=a}}function Ra(a,b){a&&X.hasOwnProperty(a)||(a=/^\s*</.test(b)?Kc:Lc);return X[a]}y(ae,[Lc]);y(K([],[[S,/^[^<?]+/],[Mc,/^<!\w[^>]*(?:>|$)/],[V,/^<\!--[\s\S]*?(?:-\->|$)/],[T,/^<\?([\s\S]+?)(?:\?>|$)/],[T,/^<%([\s\S]+?)(?:%>|$)/],[Y,/^(?:<[%?]|[%?]>)/],[T,/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],[Z,/^<script\b[^>]*>([\s\S]+?)<\/script\b[^>]*>/i],[$,/^<style\b[^>]*>([\s\S]+?)<\/style\b[^>]*>/i],
[Nc,/^(<\/?[a-z][^<>]*>)/i]]),[Kc,Oc,Pc,Qc,Rc,Sc,Tc]);y(K([[S,/^[\s]+/,r,Uc],[Vc,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,r,rc]],[[Wc,/^^<\/?[a-z](?:[\w:-]*\w)?|\/?>$/],[Xc,/^(?!style\b|on)[a-z](?:[\w:-]*\w)?/],[Yc,/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[Y,/^[=<>\/]+/],[Z,/^on\w+\s*=\s*\"([^\"]+)\"/i],[Z,/^on\w+\s*=\s*\'([^\']+)\'/i],[Z,/^on\w+\s*=\s*([^\"\'>\s]+)/i],[$,/^sty\w+\s*=\s*\"([^\"]+)\"/i],[$,/^sty\w+\s*=\s*\'([^\']+)\'/i],[$,/^sty\w+\s*=\s*([^\"\'>\s]+)/i]]),[Zc]);y(K([],[[Vc,/^[\s\S]+/]]),
[$c]);y(C({keywords:ad,hashComments:o,cStyleComments:o}),[bd,cd,dd,ed,fd,gd]);y(C({keywords:hd}),[id]);y(C({keywords:jd,hashComments:o,cStyleComments:o}),[kd]);y(C({keywords:ld,cStyleComments:o}),[md]);y(C({keywords:nd,hashComments:o,multiLineStrings:o}),[od,pd,qd]);y(C({keywords:rd,hashComments:o,multiLineStrings:o,tripleQuotedStrings:o}),[sd,td]);y(C({keywords:ud,hashComments:o,multiLineStrings:o,regexLiterals:o}),[vd,wd,xd]);y(C({keywords:yd,hashComments:o,multiLineStrings:o,regexLiterals:o}),
[zd]);y(C({keywords:Ad,cStyleComments:o,regexLiterals:o}),[Bd]);y(K([],[[U,/^[\s\S]+/]]),[Cd]);function Sa(a){var b=a.e,c=a.d;a.a=b;try{var d=Zd(b),g=d.source;a.source=g;a.b=0;a.f=d.tags;Ra(c,g)(a);be(a)}catch(i){if(Ic in window){console.log(i);console.h()}}}function ce(a,b){var c={e:a,d:b};Sa(c);return c.a}function de(a){for(var b=window._pr_isIE6(),c=[document.getElementsByTagName(Dd),document.getElementsByTagName(Ed),document.getElementsByTagName(Fd)],d=[],g=0;g<c.length;++g)for(var i=0,m=c[g].length;i<
m;++i)d.push(c[g][i]);c=r;var l=Date;l.now||(l={now:function(){return(new Date).getTime()}});var n=0,q;function v(){for(var j=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;n<d.length&&l.now()<j;n++){var f=d[n];if(f.className&&f.className.indexOf(Gd)>=0){var s=f.className.match(/\blang-(\w+)\b/);if(s)s=s[1];for(var k=z,h=f.parentNode;h;h=h.parentNode)if((h.tagName===Dd||h.tagName===Ed||h.tagName===Fd)&&h.className&&h.className.indexOf(Gd)>=0){k=o;break}if(!k){var e=Td(f);e=e.replace(/(?:\r\n?|\n)$/,
P);q={e:e,d:s,g:f};Sa(q);w()}}}if(n<d.length)setTimeout(v,250);else a&&a()}function w(){var j=q.a;if(j){var f=q.g;if(Ma(f)){for(var s=document.createElement(gc),k=0;k<f.attributes.length;++k){var h=f.attributes[k];if(h.specified){var e=h.name.toLowerCase();if(e===Hd)s.className=h.value;else s.setAttribute(h.name,h.value)}}s.innerHTML=j;f.parentNode.replaceChild(s,f);f=s}else f.innerHTML=j;if(b&&f.tagName===gc)for(var p=f.getElementsByTagName(Id),t=p.length;--t>=0;){var u=p[t];u.parentNode.replaceChild(document.createTextNode(Jd),
u)}}}v()}window.PR_normalizedHtml=W;window.prettyPrintOne=ce;window.prettyPrint=de;window.PR={combinePrefixPatterns:Na,createSimpleLexer:K,registerLangHandler:y,sourceDecorator:C,PR_ATTRIB_NAME:Xc,PR_ATTRIB_VALUE:Vc,PR_COMMENT:V,PR_DECLARATION:Mc,PR_KEYWORD:uc,PR_LITERAL:yc,PR_NOCODE:lc,PR_PLAIN:S,PR_PUNCTUATION:Y,PR_SOURCE:oc,PR_STRING:U,PR_TAG:Wc,PR_TYPE:zc}})();
})()

View File

@ -19,6 +19,9 @@
<supersedes/>
<supersededby/>
<shortname>privacy</shortname>
<schemaloc>
<url>http://xmpp.org/schemas/privacy.xsd</url>
</schemaloc>
&pgmillard;
&stpeter;
<revision>

View File

@ -38,9 +38,12 @@
&stpeter;
<revision>
<version>2.5rc1</version>
<date>2014-06-20</date>
<date>2015-09-22</date>
<initials>editor(mam)</initials>
<remark><p>Errata submitted to standards@ regarding subscriptions and returned items.</p></remark>
<remark>
<p>Errata submitted to standards@ regarding subscriptions and returned items.</p>
<p>Clarify that feature elements must be childless to make the text match the schema.</p>
</remark>
</revision>
<revision>
<version>2.4</version>
@ -267,7 +270,7 @@
]]></example>
<p>The target entity then MUST either return an IQ result, or return an error (see the <link url="#errors">Error Conditions</link> section of this document). The result MUST contain a &lt;query/&gt; element qualified by the 'http://jabber.org/protocol/disco#info' namespace, which in turn contains one or more &lt;identity/&gt; elements and one or more &lt;feature/&gt; elements. (Note: Every entity MUST have at least one identity, and every entity MUST support at least the 'http://jabber.org/protocol/disco#info' feature; however, an entity is not required to return a result and MAY return an error, most likely &feature; or &unavailable;, although other error conditions may be appropriate.)</p>
<p>Each &lt;identity/&gt; element MUST possess the 'category' and 'type' attributes specifying the category and type for the entity, and MAY possess a 'name' attribute specifying a natural-language name for the entity; the &lt;identity/&gt; element MAY also possess a standard 'xml:lang' attribute, which enables the entity to return localized results if desired (i.e., the &lt;query/&gt; element MAY include multiple &lt;identity/&gt; elements with the same category+type but with different 'xml:lang' values, however the &lt;query/&gt; element MUST NOT include multiple &lt;identity/&gt; elements with the same category+type+xml:lang but with different 'name' values).</p>
<p>Each &lt;feature/&gt; element MUST possess a 'var' attribute whose value is a protocol namespace or other feature offered by the entity.</p>
<p>Each &lt;feature/&gt; element MUST possess a 'var' attribute whose value is a protocol namespace or other feature offered by the entity, and MUST NOT have any children.</p>
<p>Preferably, both the category/type values and the feature values will be registered in a public registry, as described in the <link url="#registrar">XMPP Registrar Considerations</link> section of this document.</p>
<example caption='Result-set for information request'><![CDATA[
<iq type='result'

View File

@ -25,6 +25,12 @@
<url>http://www.xmpp.org/schemas/commands.xsd</url>
</schemaloc>
&linuxwolf;
<revision>
<version>1.2.1</version>
<date>2015-10-15</date>
<initials>XEP Editor (mam)</initials>
<remark>Corrected text regarding "xml:lang" is an attribute not an element (Christian Schudt).</remark>
</revision>
<revision>
<version>1.2</version>
<date>2005-06-30</date>
@ -660,7 +666,7 @@
<td>The command should be completed (if possible).</td>
</tr>
</table>
<p>The "xml:lang" attribute specifies the language/locale this &lt;command/&gt; is intended for. This element MAY be specified by the requester to request a specific language/locale, and SHOULD be included by the responder to indicate the language/locale in use.</p>
<p>The "xml:lang" attribute specifies the language/locale this &lt;command/&gt; is intended for. This attribute MAY be specified by the requester to request a specific language/locale, and SHOULD be included by the responder to indicate the language/locale in use.</p>
<p>The children of a &lt;command/&gt; element (other than &lt;actions/&gt; and &lt;note/&gt;) pertain to the command's execution. The order of these elements denote their precedence, so that those elements earlier in the list have higher precedence.</p>
</section2>
<section2 topic='&lt;actions/&gt; Element' anchor='desc-actions'>

View File

@ -4261,7 +4261,7 @@ And by opposing end them?
<example caption='Node or service does not support subscription management'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
id='purge1'>
id='subman1'>
<error type='cancel'>
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<unsupported xmlns='http://jabber.org/protocol/pubsub#errors'
@ -4287,7 +4287,7 @@ And by opposing end them?
<example caption='Node does not exist'><![CDATA[
<iq type='error'
from='pubsub.shakespeare.lit'
id='purge1'>
id='subman1'>
<error type='cancel'>
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>

View File

@ -29,6 +29,16 @@
&linuxwolf;
&stpeter;
&infiniti;
<revision>
<version>1.8.1</version>
<date>2015-09-17</date>
<initials>fs</initials>
<remark>
<ul>
<li>Fixed description of activate element in 9.4.</li>
</ul>
</remark>
</revision>
<revision>
<version>1.8</version>
<date>2011-04-20</date>
@ -776,7 +786,7 @@ DATA = (payload)
<p>The "jid" attribute specifies the JID of the StreamHost. This attribute MUST be present, and MUST be a valid JID for communication over XMPP.</p>
</section2>
<section2 topic='&lt;activate/&gt; Element' anchor='desc-activate'>
<p>The &lt;activate/&gt; element is sent from the Requester to the Proxy in order to formally start the bytestream. This element is always empty and has no defined attributes.</p>
<p>The &lt;activate/&gt; element is sent from the Requester to the Proxy in order to formally start the bytestream. This element has no defined attributes and its XML character data specifies the JID of the target.</p>
</section2>
<section2 topic='&lt;udpsuccess/&gt; Element' anchor='desc-udpsuccess'>
<p>The &lt;udpsuccess/&gt; element is sent from the StreamHost to the Target or Requester to indicate that the StreamHost has received a UDP initialization packet.</p>

View File

@ -80,7 +80,7 @@
<p>The following acronyms and characters are used herein to represent time-related concepts:</p>
<table caption='Acronyms and Characters'>
<tr><th>Term</th><th>Definition</th></tr>
<tr><td>CCYY</td><td>four-digit year portion of Date</td></tr>
<tr><td>CCYY</td><td>four-digit year portion of Date <note>According to the XML schema datatypes specification &lt;<link url='http://www.w3.org/TR/xmlschema11-2/#dateTime'>http://www.w3.org/TR/xmlschema11-2/#dateTime</link>&gt;, the year portion of a Date can be more than four digits (for years after 9999) and can be preceded by a minus sign (for years before 1 BCE); given that Jabber/XMPP technologies did not exist before 1999, the use of the minus sign is not recommended.</note></td></tr>
<tr><td>MM</td><td>two-digit month portion of Date</td></tr>
<tr><td>DD</td><td>two-digit day portion of Date</td></tr>
<tr><td>-</td><td>ISO 8601 separator among Date portions</td></tr>
@ -102,7 +102,7 @@
<code>
CCYY-MM-DD
</code>
<p>This profile is equivalent to the 'date' datatype defined in XML Schema <note>The 'date' datatype is defined at &lt;<link url='http://www.w3.org/TR/xmlschema-2/#date'>http://www.w3.org/TR/xmlschema-2/#date</link>&gt;.</note>. When an XML schema is used to define an XMPP protocol extension that uses this profile, the datatype MUST be an XML Schema 'date'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
<p>This profile is equivalent to the 'date' datatype defined in XML Schema <note>The 'date' datatype is defined at &lt;<link url='http://www.w3.org/TR/xmlschema11-2/#date'>http://www.w3.org/TR/xmlschema11-2/#date</link>&gt;.</note>. When an XML schema is used to define an XMPP protocol extension that uses this profile, the datatype MUST be an XML Schema 'date'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
<example caption='The date of American independence'>
1776-07-04
</example>
@ -113,7 +113,7 @@
CCYY-MM-DDThh:mm:ss[.sss]TZD
</code>
<p>The Time Zone Definition is mandatory and MUST be either UTC (denoted by addition of the character 'Z' to the end of the string) or some offset from UTC (denoted by addition of '[+|-]' and 'hh:mm' to the end of the string). The fractions of a second are optional and MAY be ignored if included (although an XMPP protocol extension using the DateTime profile MAY require the fractions of a second).</p>
<p>This profile is equivalent to the 'dateTime' datatype defined in XML Schema <note>The 'dateTime' datatype is defined at &lt;<link url='http://www.w3.org/TR/xmlschema-2/#dateTime'>http://www.w3.org/TR/xmlschema-2/#dateTime</link>&gt;.</note>. When an XML schema is used to define a Jabber protocol that uses this profile, the datatype MUST be an XML Schema 'dateTime'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
<p>This profile is equivalent to the 'dateTime' datatype defined in XML Schema <note>The 'dateTime' datatype is defined at &lt;<link url='http://www.w3.org/TR/xmlschema11-2/#dateTime'>http://www.w3.org/TR/xmlschema11-2/#dateTime</link>&gt;.</note>. When an XML schema is used to define a Jabber protocol that uses this profile, the datatype MUST be an XML Schema 'dateTime'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
<example caption='Datetime of the first human steps on the Moon (UTC)'>
1969-07-21T02:56:15Z
</example>
@ -127,7 +127,7 @@
hh:mm:ss[.sss][TZD]
</code>
<p>The Time Zone Definition is optional; if included, it MUST be either UTC (denoted by addition of the character 'Z' to the end of the string) or some offset from UTC (denoted by addition of '[+|-]' <note>Inclusion of the '+' character means that the time in that zone is ahead of UTC; e.g., a Time Zone Definition of "+07:00" means that if the UTC time is 12:00 then the local time is 19:00 (typically this is true of an area that is east of 0&#176; degrees latitude and west of 180&#176; latitude, such as Bangkok, Thailand). Inclusion of the '-' character means that the time in that zone is behind UTC; e.g., a Time Zone Definition of "-07:00" means that if the UTC time is 12:00 then the local time is 05:00 (typically this is true of an area that is west of 0&#176; degrees latitude and east of 180&#176; latitude, such as Denver, Colorado, USA).</note> and 'hh:mm' to the end of the string). The fractions of a second are optional and MAY be ignored if included (although a Jabber protocol using the DateTime profile MAY require the fractions of a second).</p>
<p>This profile is equivalent to the 'time' datatype defined in XML Schema <note>The 'time' datatype is defined at &lt;<link url='http://www.w3.org/TR/xmlschema-2/#time'>http://www.w3.org/TR/xmlschema-2/#time</link>&gt;.</note>. When an XML schema is used to define a Jabber protocol that uses this profile, the datatype MUST be an XML Schema 'time'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
<p>This profile is equivalent to the 'time' datatype defined in XML Schema <note>The 'time' datatype is defined at &lt;<link url='http://www.w3.org/TR/xmlschema11-2/#time'>http://www.w3.org/TR/xmlschema11-2/#time</link>&gt;.</note>. When an XML schema is used to define a Jabber protocol that uses this profile, the datatype MUST be an XML Schema 'time'. If there are differences between the description in this document and those in XML Schema, the latter overrule.</p>
<example caption='Time for tea'>
16:00:00
</example>

View File

@ -50,6 +50,12 @@
<surname>Raymond</surname>
<email>braymond@echostorm.net</email>
</author>
<revision>
<version>1.1.1</version>
<date>2015-10-15</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Corrected XML schema to note a number of constructs are optional not required (Christian Schudt).</p></remark>
</revision>
<revision>
<version>1.1</version>
<date>2011-06-15</date>
@ -416,7 +422,7 @@
<xs:element name='x'>
<xs:complexType>
<xs:element ref='source' use='required'/>
<xs:element ref='source' use='optional'/>
<xs:sequence>
<xs:element ref='translation' use='required' minOccurs='1'/>
</xs:sequence>
@ -439,8 +445,8 @@
<xs:extension base='empty'>
<xs:attribute name='charset' type='xs:string' use='optional'/>
<xs:attribute name='source_lang' type='xs:language' use='optional' />
<xs:attribute name='destination_lang' type='xs:string' use='required'/>
<xs:attribute name='dictionary' type='xs:string' use='required'/>
<xs:attribute name='destination_lang' type='xs:language' use='required'/>
<xs:attribute name='dictionary' type='xs:string' use='optional'/>
<xs:attribute name='engine' type='xs:string' use='optional' />
<xs:attribute name='reviewed' type='xs:boolean' use='optional' default='false'/>
</xs:extension>

View File

@ -197,6 +197,7 @@ ver=QgayPKawpkPSDYmwT/WM94uAlu0=
<p>Other people at the hotspot can also advertise similar DNS records for use on the local link. Essentially, the mDNS daemons running on all of the machines at the hotspot collectively manage the ".local." domain, which has meaning only at the hotspot (not across the broader Internet). Queries and responses for services on the local link occur via multicast DNS over UDP port 5353 instead of via normal DNS unicast over UDP port 53. When a new machine joins the local link, it can send out queries for any number of service types, to which the other machines will reply. For the purpose of serverless messaging we are interested only in the "presence" service, but many other services could exist on the local link (see <link url='http://www.dns-sd.org/'>dns-sd.org</link> for a complete list).</p>
<p>Now let us imagine that a fine young gentleman named Romeo joins the hotspot and that his chat client (actually his mDNS daemon) sends out multicast DNS queries for services of type "presence". To do this, his client essentially reverses the order of DNS record publication (explained above) by asking for pointers to presence services (i.e., PTR records that match "_presence._tcp.local."), querying each service for its service instance and port (i.e., SRV record), mapping each service instance to an IP address (i.e., A record), and finding out additional information about the entity using the service (i.e., TXT record parameters). <note>As explained in the DNS-SD specification, these queries might all be returned in the same answer.</note> As a result, Romeo's client will discover any number of local presence services, among them a service named "juliet@pronto" (with some intriguing TXT record parameters) at IP address 10.2.1.187 and port 5562. Being a romantic fellow, he then initiates a chat with you by opening an XML stream to the advertised IP address and port.</p>
<code><![CDATA[
<?xml version='1.0'?>
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
@ -206,6 +207,7 @@ ver=QgayPKawpkPSDYmwT/WM94uAlu0=
]]></code>
<p>Your client then responds with a response stream header.</p>
<code><![CDATA[
<?xml version='1.0'?>
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
@ -362,7 +364,8 @@ juliet@pronto._presence._tcp.local. IN TXT
<p>In order to exchange serverless messages, the initiator and recipient MUST first establish XML streams between themselves, as is familiar from <cite>RFC 6120</cite>.</p>
<p>First, the initiator opens a TCP connection at the IP address and port discovered via the DNS lookup for an entity and opens an XML stream to the recipient, which SHOULD include 'to' and 'from' address:</p>
<example caption="Initiator Opens a Stream"><![CDATA[
I: <stream:stream
I: <?xml version='1.0'?>
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
from='romeo@forza'
@ -372,7 +375,8 @@ I: <stream:stream
<p>Note: If the initiator supports stream features and the other stream-related aspects of XMPP 1.0 as specified in <cite>RFC 6120</cite>, then it SHOULD include the version='1.0' flag as shown in the previous example.</p>
<p>The recipient then responds with a stream header as well:</p>
<example caption="Recipient Sends Stream Header Response"><![CDATA[
R: <stream:stream
R: <?xml version='1.0'?>
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
from='juliet@pronto'
@ -426,7 +430,8 @@ I: </stream:stream>
<p>As with Entity Capabilities over native XMPP networks, a client might not know the &xep0030; features associated with the 'ver' value advertised by another entity. However, in the case of serverless messaging there is no way for the client to discover the entity's supported features without initiating an XML stream to that entity and then sending a Service Discovery information ("disco#info") request over the negotiated stream.</p>
<p>Unfortunately, full stream negotiation (including TLS and SASL if appropriate) can require a large number of packets. Therefore, as an optimization, it is RECOMMENDED for the receiving entity in a serverless XML stream negotiation to include its disco#info data (including node) as a stream feature, as shown in the following examples.</p>
<example caption="Initiator Opens a Stream"><![CDATA[
I: <stream:stream
I: <?xml version='1.0'?>
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
from='romeo@forza'
@ -434,7 +439,8 @@ I: <stream:stream
version='1.0'>
]]></example>
<example caption="Recipient Sends Stream Header Response"><![CDATA[
R: <stream:stream
R: <?xml version='1.0'?>
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
from='juliet@pronto'

View File

@ -28,6 +28,18 @@
&fabio;
&dcridland;
&mwild;
<interim/>
<revision>
<version>1.4rc1</version>
<date>2015-07-27</date>
<initials>dc</initials>
<remark>
<ul>
<li>Expressed how to handle duplicate enable requests.</li>
<li>Noted the use of delay stamping in redelivery/offline messaging by servers.</li>
</ul>
</remark>
</revision>
<revision>
<version>1.3</version>
<date>2011-06-29</date>
@ -224,6 +236,8 @@ S: <failed xmlns='urn:xmpp:sm:3'>
<unexpected-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</failed>
]]></example>
<p>Note that a client SHALL only make at most one attempt to enable stream management. If a server receives a second &lt;enable/> element it SHOULD respond with a stream error, thus terminating the client connection
.</p>
</section1>
<section1 topic='Acks' anchor='acking'>
@ -278,7 +292,7 @@ S: <a xmlns='urn:xmpp:sm:3' h='1'/>
<p>When a party receives an &lt;a/&gt; element, it SHOULD keep a record of the 'h' value returned as the sequence number of the last handled outbound stanza for the current stream (and discard the previous value).</p>
<p>If a stream ends and it is not resumed within the time specified in the original &lt;enabled/&gt; element, the sequence number and any associated state MAY be discarded by both parties. Before the session state is discarded, implementations SHOULD take alternative action regarding any unhandled stanzas (i.e., stanzas sent after the most recent 'h' value received):</p>
<ul>
<li>A server SHOULD treat unacknowledged stanzas in the same way that it would treat a stanza sent to an unavailable resource, by either returning an error to the sender or committing the stanza to offline storage.</li>
<li>A server SHOULD treat unacknowledged stanzas in the same way that it would treat a stanza sent to an unavailable resource, by either returning an error to the sender, delivery to an alternate resource, or committing the stanza to offline storage. (Note that servers SHOULD add a delay element with the original (failed) delivery timestamp, as per &xep0203;).</li>
<li>A user-oriented client SHOULD try to silently resend the stanzas upon reconnection or inform the user of the failure via appropriate user-interface elements.</li>
</ul>
<p>Because unacknowledged stanzas might have been received by the other party, resending them might result in duplicates; there is no way to prevent such a result in this protocol, although use of the XMPP 'id' attribute on all stanzas can at least assist the intended recipients in weeding out duplicate stanzas.</p>

View File

@ -23,6 +23,21 @@
&stpeter;
&seanegan;
&mlundblad;
&lance;
<revision>
<version>0.7</version>
<date>2015-10-20</date>
<initials>ls</initials>
<remark>
<ul>
<li>Clarified which attributes are needed to identify a service when requesting credentials.</li>
<li>Added 'action' attribute to indicate if a service is being added/removed/updated in a push update.</li>
<li>Added 'expires' attribute to indicate when provided credentials will expire.</li>
<li>Added 'restricted' attribute to indicate the need for fetching credentials for a service.</li>
<li>Bumped namespace version.</li>
</ul>
</remark>
</revision>
<revision>
<version>0.6</version>
<date>2014-02-27</date>
@ -111,7 +126,7 @@
</section1>
<section1 topic='Protocol' anchor='protocol'>
<p>In order to learn about external services known to an XMPP server or discovery service, a requesting entity (typically a client) sends an IQ-get containing an empty &lt;services/&gt; element qualified by the 'urn:xmpp:extdisco:1' namespace &NSNOTE;, typically to its own server but perhaps alternatively to a dedicated discovery service.</p>
<p>In order to learn about external services known to an XMPP server or discovery service, a requesting entity (typically a client) sends an IQ-get containing an empty &lt;services/&gt; element qualified by the 'urn:xmpp:extdisco:2' namespace &NSNOTE;, typically to its own server but perhaps alternatively to a dedicated discovery service.</p>
<p>The responding entity (XMPP server or discovery service) SHOULD return the list of external services it is aware of, but MAY instead return an appropriate error, such as &unavailable; if the responding entity does not support this protocol or &forbidden; if the requesting entity does not have permission to receive the list of external services. Each service is encapsulated via a &lt;service/&gt; element.</p>
<p>Note: The processes by which a responding entity discovers external services for "proxying" to XMPP entities are out of scope for this specification.</p>
<p>The &lt;service/&gt; element MAY be empty or MAY include extended information about the service as described in the <link url='#extended'>Extended Information</link> section of this document.</p>
@ -122,6 +137,16 @@
<th>Definition</th>
<th>Inclusion</th>
</tr>
<tr>
<td>action</td>
<td>When sending a push update, the action value indicates if the service is being added or deleted from the set of known services (or simply being modified). The defined values are "add", "remove", and "modify", where "add" is the default.</td>
<td>OPTIONAL</td>
</tr>
<tr>
<td>expires</td>
<td>A timestamp indicating when the provided username and password credentials will expire. The format MUST adhere to the dateTime format specified in &xep0082; and MUST be expressed in UTC.</td>
<td>OPTIONAL</td>
</tr>
<tr>
<td>host</td>
<td>Either a fully qualified domain name (FQDN) or an IP address (IPv4 or IPv6).</td>
@ -142,6 +167,11 @@
<td>The communications port to be used at the host.</td>
<td>RECOMMENDED</td>
</tr>
<tr>
<td>restricted</td>
<td>A boolean value indicating that username and password credentials are required and will need to be requested if not already provided (see <link url="#credentials">Requesting Credentials</link>).</td>
<td>OPTIONAL</td>
</tr>
<tr>
<td>transport</td>
<td>The underlying transport protocol to be used when communicating with the service (typically either TCP or UDP).</td>
@ -169,7 +199,7 @@
id='ul2bc7y6'
to='shakespeare.lit'
type='get'>
<services xmlns='urn:xmpp:extdisco:1'/>
<services xmlns='urn:xmpp:extdisco:2'/>
</iq>
]]></example>
<example caption='XMPP Server Returns List'><![CDATA[
@ -177,7 +207,7 @@
id='ul2bc7y6'
to='bard@shakespeare.lit/globe'
type='result'>
<services xmlns='urn:xmpp:extdisco:1'>
<services xmlns='urn:xmpp:extdisco:2'>
<service host='stun.shakespeare.lit'
port='9998'
transport='udp'
@ -216,7 +246,7 @@
id='yv2c19f7'
to='shakespeare.lit'
type='get'>
<services xmlns='urn:xmpp:extdisco:1' type='turn'/>
<services xmlns='urn:xmpp:extdisco:2' type='turn'/>
</iq>
]]></example>
<example caption='XMPP Server Returns List'><![CDATA[
@ -224,7 +254,7 @@
id='yv2c19f7'
to='bard@shakespeare.lit/globe'
type='result'>
<services xmlns='urn:xmpp:extdisco:1'
<services xmlns='urn:xmpp:extdisco:2'
type='turn'>
<service host='turn.shakespeare.lit'
password='jj929jkj5sadjfj93v3n'
@ -241,40 +271,46 @@
</services>
</iq>
]]></example>
<p>If a requesting entity requests services of a particular type, the responding service MAY as needed send an updated list of the relevant services by "pushing" the list to a requesting entity that has previously requested the list. However, it MUST NOT push updates to the requesting entity unless it has presence information about the requesting entity (e.g., because the requesting entity is connected to the XMPP server or because the requesting entity has shared presence with a remote discovery service). A push is an IQ set to the requesting entity containing a &lt;service/&gt; payload with updated data about services matching the requested type (e.g., new services or updated credentials)</p>
<p>If a requesting entity requests services of a particular type, the responding service MAY as needed send an updated list of the relevant services by "pushing" the list to a requesting entity that has previously requested the list. However, it MUST NOT push updates to the requesting entity unless it has presence information about the requesting entity (e.g., because the requesting entity is connected to the XMPP server or because the requesting entity has shared presence with a remote discovery service). A push is an IQ set to the requesting entity containing a &lt;services/&gt; payload with updated data about services matching the requested type (e.g., new services or updated credentials). Each &lt;service/&gt; element SHOULD contain an 'action' attribute indicating if the service is being added, deleted, or modified.</p>
<example caption='Services Push'><![CDATA[
<iq from='shakespeare.lit'
id='lh3f1vc7'
to='bard@shakespeare.lit/globe'
type='set'>
<services xmlns='urn:xmpp:extdisco:1'
<services xmlns='urn:xmpp:extdisco:2'
type='turn'>
<service host='stun.shakespeare.lit'
<service action='add'
host='stun.shakespeare.lit'
port='9999'
transport='udp'
type='turn'
username='1nas9dlm3hzl89d0b9v'
password='gh9023ljjdk109iajqn'>
<service host='192.0.2.2'
<service action='add'
host='192.0.2.2'
port='7778'
transport='udp'
type='turn'
username='bnsv120afg48snsdozp'
password='zxp023na98dsfahn1kk'/>
<service action='delete'
host='192.0.2.1'
port='8889'
type='turn'/>
</services>
</iq>
]]></example>
<p>Upon receiving a push, the requesting entity would then send an IQ-result to the responding service in accordance with &xmppcore;.</p>
</section2>
<section2 topic='Requesting Credentials' anchor='credentials'>
<p>An entity might know about an external service via DNS or some other means, but still might need short-term credentials to use the service. The entity can request credentials by sending a special request to the server.</p>
<p>An entity might know about an external service via DNS or some other means, but still might need short-term credentials to use the service. The entity can request credentials by sending a special request to the server composed of a &lt;credentials/&gt; element qualified by the 'urn:xmpp:extdisco:2' namespace and contains a &lt;service/&gt; element which MUST include the 'host' and 'type' attributes to identify the desired service (the 'port' attribute MAY be provided if there are multiple services with the same host and type but different ports).</p>
<example caption='Entity Requests Credentials at a Service'><![CDATA[
<iq from='bard@shakespeare.lit/globe'
id='xi2cax48'
to='shakespeare.lit'
type='get'>
<credentials xmlns='urn:xmpp:extdisco:1'>
<service host='turn.shakespeare.lit'/>
<credentials xmlns='urn:xmpp:extdisco:2'>
<service host='turn.shakespeare.lit' type='turn' />
</credentials>
</iq>
]]></example>
@ -284,23 +320,25 @@
id='xi2cax48'
to='bard@shakespeare.lit/globe'
type='get'>
<credentials xmlns='urn:xmpp:extdisco:1'>
<credentials xmlns='urn:xmpp:extdisco:2'>
<service host='turn.shakespeare.lit'
type='turn'
password='jj929jkj5sadjfj93v3n'
username='nb78932lkjlskjfdb7g8'/>
</credentials>
</iq>
]]></example>
<p>For TURN, the server might construct time-limited credentials as described in &turn-rest;.</p>
<p>There MAY be multiple &lt;service/&gt; elements in the result if more than one service matched the requested service identity (e.g., the same host provides service on multiple ports).</p>
<p>If the server cannot obtain credentials at the service, it returns an appropriate stanza error, such as &notfound;, &remoteserver;, &timeout;, or &notauthorized;.</p>
</section2>
</section1>
<section1 topic='Extended Information' anchor='extended'>
<p>If a server or service needs to include extended information, it SHOULD do so by including each bit of information as the XML character data of the &lt;value/&gt; child of a distinct &lt;field/&gt; element, with the entire set of fields contained within an &lt;x/&gt; element of type "result" qualified by the 'jabber:x:data' namespace (see &xep0004;); this &lt;x/&gt; element SHOULD be a child of the &lt;service/&gt; element qualified by the 'urn:xmpp:extdisco:1' namespace &NSNOTE;. Thus the IQ result SHOULD be of the following form:</p>
<p>If a server or service needs to include extended information, it SHOULD do so by including each bit of information as the XML character data of the &lt;value/&gt; child of a distinct &lt;field/&gt; element, with the entire set of fields contained within an &lt;x/&gt; element of type "result" qualified by the 'jabber:x:data' namespace (see &xep0004;); this &lt;x/&gt; element SHOULD be a child of the &lt;service/&gt; element qualified by the 'urn:xmpp:extdisco:2' namespace &NSNOTE;. Thus the IQ result SHOULD be of the following form:</p>
<code><![CDATA[
<iq type='result'>
<services xmlns='urn:xmpp:extdisco:1'>
<services xmlns='urn:xmpp:extdisco:2'>
<service>
<x type='result' xmlns='jabber:x:data'>
<field var='[var-name]' label='[optional]'>
@ -317,7 +355,7 @@
</section1>
<section1 topic='Determining Support' anchor='disco'>
<p>If an XMPP entity supports this protocol, it MUST report that fact by including a service discovery feature of "urn:xmpp:extdisco:1" &NSNOTE; in response to a &xep0030; information request:</p>
<p>If an XMPP entity supports this protocol, it MUST report that fact by including a service discovery feature of "urn:xmpp:extdisco:2" &NSNOTE; in response to a &xep0030; information request:</p>
<example caption="Service Discovery Information Request"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='ix61z3m9'
@ -332,7 +370,7 @@
to='romeo@montague.lit/orchard'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<feature var='urn:xmpp:extdisco:1'/>
<feature var='urn:xmpp:extdisco:2'/>
</query>
</iq>
]]></example>
@ -350,7 +388,7 @@
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>This specification defines the following XML namespace:</p>
<ul>
<li>urn:xmpp:extdisco:1</li>
<li>urn:xmpp:extdisco:2</li>
</ul>
<p>Upon advancement of this specification from a status of Experimental to a status of Draft, the &REGISTRAR; shall add the foregoing namespace to the registry located at &NAMESPACES;, as described in Section 4 of &xep0053;.</p>
</section2>
@ -394,8 +432,8 @@
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:xmpp:extdisco:1'
xmlns='urn:xmpp:extdisco:1'
targetNamespace='urn:xmpp:extdisco:2'
xmlns='urn:xmpp:extdisco:2'
elementFormDefault='qualified'>
<xs:import
@ -414,7 +452,7 @@
<xs:element name='credentials'>
<xs:complexType>
<xs:sequence>
<xs:element ref='service' minOccurs='0' maxOccurs='1'/>
<xs:element ref='service' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
</xs:complexType>
</xs:element>
@ -424,10 +462,21 @@
<xs:sequence xmlns:xdata='jabber:x:data'>
<xs:element ref='xdata:x' minOccurs='0'/>
</xs:sequence>
<xs:attribute name='action' use='optional' default='add'>
<xs:simpleType>
<xs:restriction base='xs:NCName'>
<xs:enumeration value='add'/>
<xs:enumeration value='delete'/>
<xs:enumeration value='modify'/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name='expires' type='xs:dateTime' use='optional'/>
<xs:attribute name='host' type='xs:string' use='required'/>
<xs:attribute name='name' type='xs:string' use='optional'/>
<xs:attribute name='password' type='xs:string' use='optional'/>
<xs:attribute name='port' type='xs:string' use='required'/>
<xs:attribute name='restricted' type='xs:boolean' use='optional'/>
<xs:attribute name='transport' type='xs:NCName' use='optional'/>
<xs:attribute name='type' type='xs:NCName' use='required'/>
<xs:attribute name='username' type='xs:string' use='optional'/>

View File

@ -6,11 +6,11 @@
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Domain-Based Service Names in XMPP SASL Negotiation</title>
<abstract>This specification defines a method by a connecting client can learn the domain-based service name of a Kerberos acceptor principal for SASL authentication using the GSSAPI mechanism.</abstract>
<title>XMPP Server Registration for use with Kerberos V5</title>
<abstract>This specification defines the Kerberos principal name of an XMPP server. It also details a method by which a connecting client can determine this Kerberos principal name when authenticating using the "GSSAPI" SASL mechanism.</abstract>
&LEGALNOTICE;
<number>0233</number>
<status>Deferred</status>
<status>Experimental</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -25,6 +25,12 @@
&linuxwolf;
&stpeter;
&hildjj;
<revision>
<version>0.5</version>
<date>2015-10-20</date>
<initials>mv</initials>
<remark><p>Included support for Microsoft SSPI (Mili Verma).</p></remark>
</revision>
<revision>
<version>0.4</version>
<date>2011-08-26</date>
@ -64,18 +70,52 @@
</header>
<section1 topic='Introduction' anchor='intro'>
<p>In environments that make use of Kerberos V5 (&rfc4120;) and negotiation of Simple Authentication and Security Layer or SASL (&rfc4422;) over XMPP, a connecting client often needs to know the identity of the Kerberos acceptor principal so that it can obtain a proper ticket for authentication. This scenario was not addressed in &rfc3920; or &rfc6120;. However, the problem can be solved using the concept of domain-based service names (&rfc5178;). In particular, when an XMPP server uses the Kerberos V5 ("GSSAPI") SASL mechanism (&rfc4752;), it can communicate the identity of the acceptor principal as a Kerberos V5 service principal name (&rfc5179;). This document defines an XMPP method for such communication.</p>
<p>The Kerberos Network Authentication Service (V5) is described in &rfc4120;. An application can call the Kerberos library through the Generic Security Services Application Programming Interface (GSS-API) described in &rfc4121; or the proprietary Microsoft Windows Security Service Provider Interface (SSPI).</p>
<p>The Simple Authentication and Security Layer or SASL (&rfc4422;) is a framework for adding authentication support to connection-based protocols. The SASL mechanism used in environments that make use of Kerberos V5 is called "GSSAPI" and is described in &rfc4752;. Note that the <cite>RFC 4121</cite> API has a hyphen and the SASL mechanism does not.</p>
<p>Before using the "GSSAPI" SASL mechanism to authenticate to an XMPP server (which is referred to as the "acceptor" in Kerberos terminology), a connecting client needs to obtain a Kerberos ticket from the Key Distribution Centre (KDC). For this the client needs to determine the Kerberos principal name of the XMPP server. This scenario was not addressed in &rfc3920; or &rfc6120;.</p>
<p>This specification sets out the rules that must be followed when registering the Kerberos principal name of an XMPP server. It also details how a client can determine the hostname of the XMPP server which can then be used to construct the Kerberos principal name.</p>
</section1>
<section1 topic='Protocol' anchor='proto'>
<p>The acceptor principal's hostname is communicated by including a child element of the &lt;mechanisms/&gt; element during SASL negotation, as allowed by <cite>RFC 6120</cite> (see Section 6.3.5 and the schema for the 'urn:ietf:params:xml:ns:xmpp-sasl' namespace in Appendix A.4). In the case of the Kerberos V5 SASL mechanism, the child element is a &lt;hostname/&gt; element qualified by the 'urn:xmpp:domain-based-name:1' namespace &NSNOTE;. The XML character data of the &lt;hostname/&gt; element specifies the fully-qualified name of the acceptor principal. The client then generates a domain-based service name from the provided hostname, following the format specified in <cite>RFC 5179</cite> (i.e., "protocol/hostname/domainname@REALM") and setting the values as follows:</p>
<section1 topic='Client Determination of Hostname' anchor='hostname'>
<p>An XMPP client will initiate a connection to the XMPP server.</p>
<p>The XMPP server will communicate its hostname in a child element of the &lt;mechanisms/&gt; element during SASL negotation, as allowed by <cite>RFC 6120</cite> (see Section 6.3.5 and the schema for the 'urn:ietf:params:xml:ns:xmpp-sasl' namespace in Appendix A.4).</p>
<p>This child element is &lt;hostname/&gt; qualified by the 'urn:xmpp:domain-based-name:1' namespace. &NSNOTE;.</p>
<p>The XML character data of the &lt;hostname/&gt; element specifies the fully-qualified name of the XMPP server. This should be used for constructing the Kerberos principal name and is independent of the usual rules that an XMPP client uses for establishing a network connection to the XMPP server.</p>
</section1>
<section1 topic='Kerberos Principal Name in the GSS-API environment' anchor='principal'>
<p>When the XMPP server is implemented using GSS-API, the domain-based service name (&rfc5178;, &rfc5179;) is used as the Kerberos principal name. Domain-based service names contain a domain name in addition to a hostname. This allows naming clustered servers after the domain which they service.</p>
<p>The domain-based service name is mapped to the Kerberos principal name following the format specified in <cite>RFC 5179</cite> (i.e., "service/hostname/domain@REALM") and setting the values as follows:</p>
<ul>
<li>The <strong>protocol</strong> string MUST be "xmpp".</li>
<li>The <strong>hostname</strong> string MUST be the XML character data of the &lt;hostname/&gt; element.</li>
<li>The <strong>domainname</strong> string MUST be the canonical name of the service, such as typically communicated in the 'to' address of the initial stream header.</li>
<li>The <strong>service</strong> string MUST be "xmpp".</li>
<li>The <strong>hostname</strong> string MUST be the hostname of the XMPP server, as provided by the server in the XML character data of the &lt;hostname/&gt; element during SASL negotiation.</li>
<li>The <strong>domain</strong> string MUST be the canonical name of the service. This is typically communicated by the client in the 'to' address of the initial stream header.</li>
<li>The <strong>REALM</strong> string SHOULD be determined according to the network policies in effect (usually the domain name, in an uppercase mapping).</li>
</ul>
<p>Consider the example of an XMPP service whose canonical name is "example.com". A user might make use of an acceptor principal located at "auth42.us.example.com". The hostname would be communicated as follows.</p>
</section1>
<section1 topic='Kerberos Principal Name in the Microsoft SSPI environment' anchor='windows'>
<p>Microsoft Windows provides the proprietary SSPI to support the "GSSAPI" SASL mechanism. This section describes the Windows equivalent of the domain-based service name for an XMPP server.</p>
<p>In the Microsoft Windows environment, the concept of Service Principal Name (SPN) is used, which is specified in <link url='https://msdn.microsoft.com/en-us/library/ms677601%28v=vs.85%29.aspx'>https://msdn.microsoft.com/en-us/library/ms677601%28v=vs.85%29.aspx</link>. This format ("service class/host:port/service name") is similar to the one specified in <cite>RFC 5179</cite>. The SPN can be generated by setting the values as follows:</p>
<ul>
<li>The <strong>service class</strong> string MUST be "xmpp".</li>
<li>The <strong>host</strong> string MUST be the hostname of the XMPP server, as provided by the server in the XML character data of the &lt;hostname/&gt; element during SASL negotiation.</li>
<li>The <strong>port</strong> is optional. It can be used to differentiate between multiple XMPP servers on a single host computer and should be omitted if the XMPP server uses the default port of 5222 for accepting client connections.</li>
<li>The <strong>service name</strong> string MUST be the canonical name of the service. This is typically communicated by the client in the 'to' address of the initial stream header.</li>
</ul>
</section1>
<section1 topic='Interoperability between GSS-API and SSPI' anchor='interop'>
<p>The goal of this section is to help developers of applications so that clients and servers implemented over SSPI can interoperate with servers and clients implemented over GSS-API.</p>
<p>Interoperability is achieved by the GSS-API system joining the Windows Active Directory domain or by having a cross-realm trust between the KDCs of the GSS-API and SSPI systems.</p>
<p>The SPN of the SSPI server does not specify a realm. A GSS-API client constucts the Kerberos principal name according to the rules in the GSS-API environment and adds a realm to the Kerberos principal name, but the Kerberos principal name is mapped to the correct XMPP server on SSPI.</p>
<p>When the server uses GSS-API, the SPN for the server needs to be created in the SSPI environment. The SPN constructed by the SSPI client according to the rules in the SSPI environment is then mapped to the correct GSS-API XMPP server.</p>
<p>The domain-based service name of GSS-API does not specify a port, so the port option of the SPN in SSPI should only be used in testing scenarios when both the XMPP client and the XMPP server are implemented using SSPI. The port SHOULD NOT be used in any other scenarios.</p>
<p>So in effect, whether an endpoint uses SSPI or GSS-API does not affect interoperability as long as the port in SSPI is not used.</p>
</section1>
<section1 topic='Examples' anchor='examples'>
<p>Consider the example of an XMPP service "example.com" offered by the XMPP server located on the host "auth42.us.example.com", using the default port of 5222 for accepting client connections. When a client connects to the XMPP server, the server communicates its hostname along with supported SASL mechanisms as follows:</p>
<example caption="Communicating the hostname"><![CDATA[
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<mechanism>GSSAPI</mechanism>
@ -83,11 +123,15 @@
<hostname xmlns='urn:xmpp:domain-based-name:1'>auth42.us.example.com</hostname>
</mechanisms>
]]></example>
<p>The client would then attempt to obtain a ticket for the domain-based principal "xmpp/auth42.us.example.com/example.com@EXAMPLE.COM".</p>
<p>To use the "GSSAPI" SASL mechanism, the client needs to determine the Kerberos principal name of the XMPP server, which will be:</p>
<ul>
<li>the domain-based service name "xmpp/auth42.us.example.com/example.com@EXAMPLE.COM" if the client is using GSS-API.</li>
<li>the SPN "xmpp/auth42.us.example.com/example.com" if the client is using SSPI.</li>
</ul>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>The communication of acceptor principal hostname during SASL negotiation is not known to introduce new security vulnerabilities, as long as it is done after the underlying channel has been secured using Transport Layer Security (TLS; &rfc5246;) as described for XMPP in <cite>RFC 6120</cite>. For additional security considerations, refer to <cite>RFC5178</cite> and <cite>RFC 5179</cite>.</p>
<p>The communication of the XMPP server's hostname during SASL negotiation is not known to introduce new security vulnerabilities, as long as it is done after the underlying channel has been secured using Transport Layer Security (TLS; &rfc5246;) as described for XMPP in <cite>RFC 6120</cite>. For additional security considerations, refer to <cite>RFC 5178</cite> and <cite>RFC 5179</cite>.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
@ -124,7 +168,7 @@
</section1>
<section1 topic='Acknowledgements' anchor='ack'>
<p>Thanks to Owen Friel, Shane Hannon, Seamus Kerrigan, Eliot Lear, Alexey Melnikov, and Klaas Wierenga for their comments.</p>
<p>Thanks to Owen Friel, Shane Hannon, Seamus Kerrigan, Eliot Lear, Alexey Melnikov, Klaas Wierenga and Dave Cridland for their comments.</p>
</section1>
</xep>

File diff suppressed because it is too large Load Diff

View File

@ -53,7 +53,7 @@
<li>Two endpoints want to enforce end-to-end encryption</li>
<li>Two endpoints want to send a high volume of XMPP traffic but the intermediate servers enforce rate limits</li>
</ul>
<p>The first situation is addressed by &xep0174;. However, if the endpoints already have client-to-server connections but wish to bypass those connections or leverage those streams for a higher-level application such as end-to-end encryption, it is desirable for the two endpoints to negotiate an end-to-end XML stream. This specification defines methods for doing so, where the application format is an XML stream and the transport method is any direct or mediated streaming transport, such as &xep0261; (mediated), &xep0260; (direct or mediated), or a future ice-tcp Jingle transport (direct or mediated) based on &ice-tcp;.</p>
<p>The first situation is addressed by &xep0174;. However, if the endpoints already have client-to-server connections but wish to bypass those connections or leverage those streams for a higher-level application such as end-to-end encryption, it is desirable for the two endpoints to negotiate an end-to-end XML stream. This specification defines methods for doing so, where the application format is an XML stream and the transport method is any direct or mediated streaming transport, such as &xep0261; (mediated), &xep0260; (direct or mediated), or a future ice-tcp Jingle transport (direct or mediated) based on &rfc6544;.</p>
</section1>
<section1 topic='Protocol' anchor='protocol'>
@ -79,7 +79,7 @@
| ack |
|------------------------------>|
| [ XML stream over IBB ] |
|<----------------------------->|
|<=============================>|
| terminate |
|<------------------------------|
| ack |
@ -118,7 +118,7 @@
id='hwd987h'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:0'>
<jingle xmlns='urn:xmpp:jingle:0'
action='session-accept'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>

View File

@ -6,11 +6,11 @@
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>File Transfer Thumbnails</title>
<abstract>This specification defines a way for a client supply a preview image for a file transfer.</abstract>
<title>Jingle Content Thumbnails</title>
<abstract>This specification defines a way for a client to supply a preview image for Jingle content.</abstract>
&LEGALNOTICE;
<number>0264</number>
<status>Deferred</status>
<status>Experimental</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -28,6 +28,17 @@
<email>ml@update.uu.se</email>
<jid>mlundblad@jabber.org</jid>
</author>
&lance;
<revision>
<version>0.4</version>
<date>2015-08-26</date>
<initials>ljts</initials>
<remark>
<p>Changed format to use generic 'uri' attribute to allow for 'https:' and 'http:' URIs in addition to BoB 'cid:' URIs.</p>
<p>Indicated that multiple thumbnails may be present.</p>
<p>Expanded scope of use cases to be Jingle content in general, not just file transfer.</p>
</remark>
</revision>
<revision>
<version>0.3</version>
<date>2009-04-27</date>
@ -69,43 +80,15 @@ Added missing namespace on thumnail elements.</p>
</revision>
</header>
<section1 topic='Introduction' anchor='introduction'>
<p>The current methods for file transfers include basic meta data about the
file being offered (name, size, and date). There currently is no way to provide an image thumbnail for files such as photos.</p>
<p>When offering a Jingle session, it can be helpful to provide a small preview of the offered content to help the session responder decide whether to accept or reject the session.</p>
<p>This is particularly useful for file transfer content (especially image files), but can also be used for things such as video (e.g. using a still frame from the stream as the preview thumbnail), and even audio by using a small image of album cover art.</p>
</section1>
<section1 topic='Requirements' anchor='requirements'>
<p>This documents defines a way to include a thumbnail image as an additional metadata in a file transfer.</p>
<p>This documents defines a way to include a thumbnail image as an additional metadata in a Jingle content description.</p>
</section1>
<section1 topic='Use Case' anchor='usecase'>
<p>When a client wishes to supply a thumbnail in a transfer offer, it can do so by including an extra <![CDATA[<thumbnail/>]]> element as shown in the following exaples.</p>
<example caption='Inclusion of a thumbnail in SI file transfer offer'><![CDATA[
<iq type='set' id='offer1' to='receiver@jabber.org/resource'>
<si xmlns='http://jabber.org/protocol/si'
id='a0'
mime-type='image/jpeg'
profile='http://jabber.org/protocol/si/profile/file-transfer'>
<file xmlns='http://jabber.org/protocol/si/profile/file-transfer'
name='image.jpg'
size='3032449'>
<thumbnail xmlns='urn:xmpp:thumbs:0'
cid='sha1+ffd7c8d28e9c5e82afea41f97108c6b4@bob.xmpp.org'
mime-type='image/png'
width='128'
height='96'/>
</file>
<feature xmlns='http://jabber.org/protocol/feature-neg'>
<x xmlns='jabber:x:data' type='form'>
<field var='stream-method' type='list-single'>
<option><value>http://jabber.org/protocol/bytestreams</value></option>
<option><value>http://jabber.org/protocol/ibb</value></option>
</field>
</x>
</feature>
</si>
</iq>
]]>
</example>
<p>The receiver MAY now request the data using the protocol defined in &xep0231;.</p>
<example caption='Inclusion of a thumbnail in a Jingle file transfer offer'><![CDATA[
<section1 topic='Use Cases' anchor='usecase'>
<p>When a client wishes to supply a thumbnail in a content offer, it can do so by including an extra &lt;thumbnail/&gt; element as shown in the following example:</p>
<example caption='Inclusion of a thumbnail in a Jingle file transfer offer'><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='nzu25s8'
to='juliet@capulet.lit/balcony'
@ -115,66 +98,99 @@ file being offered (name, size, and date). There currently is no way to provide
initiator='romeo@montague.lit/orchard'
sid='851ba2'>
<content creator='initiator' name='a-file-offer'>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:1'>
<offer>
<file xmlns='http://jabber.org/protocol/si/profile/file-transfer'
name='image.jpg'
size='3032449'
hash='552da749930852c69ae5d2141d3766b1'
date='1969-07-21T02:56:15Z'>
<desc>This is a test. If this were a real file...</desc>
<thumbnail xmlns='urn:xmpp:thumbs:0'
cid='sha1+ffd7c8d28e9c5e82afea41f97108c6b4@bob.xmpp.org'
mime-type='image/png'
width='128'
height='96'/>
</file>
</offer>
<description xmlns='urn:xmpp:jingle:apps:file-transfer:4' senders='initiator'>
<file>
<media-type>image/jpeg</media>
<name>image.jpg</name>
<size>3032449</size>
<hash xmlns='urn:xmpp:hashes:1' algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>
<desc>This is a test. If this were a real file...</desc>
<thumbnail xmlns='urn:xmpp:thumbs:1'
uri='cid:sha1+ffd7c8d28e9c5e82afea41f97108c6b4@bob.xmpp.org'
media-type='image/png'
width='128'
height='96'/>
</file>
</description>
...
<transport .../>
</content>
</jingle>
</iq>
]]>
</example>
<section2 topic='Definition of the thumbnail Element'
anchor='thumbnail_element'>
<p>The following attributes are defined for the &lt;thumbnail/&gt; element.</p>
<table caption='Attributes of the thumbnail Element'>
<tr>
<th>Attribute</th>
<th>Description</th>
<th>Inclusion</th>
</tr>
<tr>
<td>cid</td>
<td>A Content-ID that can be mapped to a cid: URL as specified in &rfc2111;. The 'cid' value SHOULD be of the form algo+hash@bob.xmpp.org, where the "algo" is the hashing algorithm used (e.g., "sha1" for the SHA-1 algorithm as specified in &rfc3174;) and the "hash" is the hex output of the algorithm applied to the binary data itself.</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>mime-type</td>
<td>The value of the 'mime-type' attribute MUST match the syntax specified in &rfc2045;. That is, the value MUST include a top-level media type, the "/" character, and a subtype; in addition, it MAY include one or more optional parameters (e.g., the "audio/ogg" MIME type in the example shown below includes a "codecs" parameter as specified in &rfc4281;). The "type/subtype" string SHOULD be registered in the &ianamedia;, but MAY be an unregistered or yet-to-be-registered value.</td>
<td>RECOMMENDED</td>
</tr>
<tr>
<td>width</td>
<td>The intended display width of the thumbnail image. Used as a hint for the receiving client to prepare i.e. a dialog window.</td>
<td>OPTIONAL</td>
</tr>
<tr>
<td>height</td>
<td>The intended display height of the thumbnail image. Used as a hint for the receiving client to prepare i.e. a dialog window.</td>
<td>OPTIONAL</td>
</tr>
</table>
</iq>]]></example>
</section2>
<p>Thumbnails MAY be included for Jingle content other than file transfer. For example, with Jingle RTP video a thumbnail could be included to show who is calling (either by capturing a still frame from the input stream or by using an existing profile image):</p>
<example caption='Inclusion of a thumbnail in a Jingle RTP video session'><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='ih28sx61'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='webcam'>
<description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'>
<payload-type id='98' name='theora' clockrate='90000'>
<parameter name='height' value='600'/>
<parameter name='width' value='800'/>
<parameter name='delivery-method' value='inline'/>
<parameter name='configuration' value='somebase16string'/>
<parameter name='sampling' value='YCbCr-4:2:2'/>
</payload-type>
<payload-type id='28' name='nv' clockrate='90000'/>
<payload-type id='25' name='CelB' clockrate='90000'/>
<payload-type id='32' name='MPV' clockrate='90000'/>
<bandwidth type='AS'>128</bandwidth>
<thumbnail xmlns='urn:xmpp:thumbs:1'
uri='cid:sha1+ffd7c8d28e9c5e82afea41f97108c6b4@bob.xmpp.org'
media-type='image/png'
width='128'
height='96'/>
</description>
<transport .../>
</content>
</jingle>
</iq>]]></example>
<p>Multiple &lt;thumbnail/&gt; elements MAY be included to provide thumbnails of different sizes, media types, or URIs.</p>
<p>If the provided URI has the scheme 'cid', then the thumbnail data MAY be requested using &xep0231;.</p>
</section1>
<section1 topic='Definition of the thumbnail Element' anchor='thumbnail_element'>
<p>The following attributes are defined for the &lt;thumbnail/&gt; element.</p>
<table caption='Attributes of the thumbnail Element'>
<tr>
<th>Attribute</th>
<th>Description</th>
<th>Inclusion</th>
</tr>
<tr>
<td>uri</td>
<td>A URI where the thumbnail data can be accessed (typically by using a URI scheme of 'cid:', 'https:', or 'http:'). If the URI scheme is 'cid:' then the identifier MUST refer to a bit of binary data as described in &xep0231;</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>media-type</td>
<td>The value of the 'media-type' attribute MUST match the syntax specified in &rfc2045;. That is, the value MUST include a top-level media type, the "/" character, and a subtype; in addition, it MAY include one or more optional parameters. The "type/subtype" string SHOULD be registered in the &ianamedia;, but MAY be an unregistered or yet-to-be-registered value.</td>
<td>RECOMMENDED</td>
</tr>
<tr>
<td>width</td>
<td>The intended display width of the thumbnail image. Used as a hint for the receiving client to prepare the appropriate UI, such as a dialog window.</td>
<td>OPTIONAL</td>
</tr>
<tr>
<td>height</td>
<td>The intended display height of the thumbnail image. Used as a hint for the receiving client to prepare the appropriate UI, such as a dialog window.</td>
<td>OPTIONAL</td>
</tr>
</table>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>The inclusion of an image thumbnail may leak information about a transfer
otherwise taking place on an e2e encrypted file transfer stream. A client MAY
wish to not include a thumbnail.</p>
<p>A client MUST NOT rely on the values specified for the width and height of a thumbnail to allocate a bitmap data buffer for the thumbnail, to prevent possible DoS attacks. Also a client SHOULD apply implementation-specific limits on the thumbnails, if using these values to pepare a UI element for the thumbnail image, of f.ex. 128x128 pixels, values exceeding these would then be truncated and the thumbnail image scaled down when received.</p>
<p>A client MUST NOT rely on the values specified for the width and height of a thumbnail to allocate a bitmap data buffer for the thumbnail, to prevent possible DoS attacks. Also a client SHOULD apply implementation-specific limits on the thumbnails, if using these values to pepare a UI element for the thumbnail image, e.g. with dimensions of 128x128 pixels, values exceeding these would then be truncated and the thumbnail image scaled down when received.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with &IANA;.</p>
@ -183,7 +199,7 @@ wish to not include a thumbnail.</p>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>This specification defines the following XML namespace:</p>
<ul>
<li>urn:xmpp:thumbs:0</li>
<li>urn:xmpp:thumbs:1</li>
</ul>
<p>The &REGISTRAR; includes this namespace in the registry located at &NAMESPACES;, as described in Section 4 of &xep0053;.</p>
</section2>
@ -210,8 +226,8 @@ wish to not include a thumbnail.</p>
<xs:element name='thumbnail'>
<xs:complexType>
<xs:attribute name='cid' type='xs:string' use='required'/>
<xs:attribute name='mime-type' type='xs:string' use='optional'/>
<xs:attribute name='uri' type='xs:anyURI' use='required'/>
<xs:attribute name='media-type' type='xs:string' use='optional'/>
<xs:attribute name='width' type='xs:integer' use='optional'/>
<xs:attribute name='height' type='xs:integer' use='optional'/>
</xs:complexType>

View File

@ -10,7 +10,8 @@
<abstract>In order to keep all IM clients for a user engaged in a conversation, outbound messages are carbon-copied to all interested resources.</abstract>
&LEGALNOTICE;
<number>0280</number>
<status>Experimental</status>
<status>Proposed</status>
<lastcall>2015-08-28</lastcall>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -39,6 +40,15 @@
<email>linuxwolf@outer-planes.net</email>
<jid>linuxwolf@outer-planes.net</jid>
</author>
<revision>
<version>0.10</version>
<date>2015-08-24</date>
<initials>mm (editor)</initials>
<remark>
<p>Removed distinction between full-JID and bare-JID when receiving messages (Georg Lukas).</p>
<p>Define rules around "elible messages", and provide reasonable default guidelines (Kevin Smith).</p>
</remark>
</revision>
<revision>
<version>0.9</version>
<date>2013-10-17</date>
@ -123,9 +133,9 @@
<li>Clients that do not implement the new protocol MUST NOT
receive protocol they do not expect</li>
<li>All clients that turn on the new protocol MUST be able to see
all inbound chat-type messages.</li>
all inbound instant messaging messages.</li>
<li>All clients that turn on the new protocol MUST be able to see
all outbound chat-type messages from all of the resources of the
all outbound instant messaging messages from all of the resources of the
user, regardless of whether the clients for the other resources
have implemented the new protocol.</li>
</ul>
@ -226,41 +236,26 @@
</ul>
<p>See the section <link url='#bizrules-multi'>Handling Multiple Enable/Disable Requests</link> for considerations when a client attempts to disable Carbons multiple times.</p>
</section2>
</section1>
</section1>
<section1 topic='Receiving Messages to the Bare JID' anchor='inbound-bare'>
<p>When the server receives a &MESSAGE; of type "chat" addressed to a bare JID (localpart@domainpart), it delivers a copy to each Carbons-enabled resource for the bare JID in addition to delivering according to <cite>RFC 6121</cite> § 8.5.2. This process is sometimes called "forking".</p>
<section1 topic='Messages Eligible for Carbons Delivery' anchor='which-messages'>
<p>The focus of this specification is instant messaging applications and so those (and only those) &MESSAGE; stanzas used for instant messaging SHOULD be delivered as Carbons. Defining precisely which messages are used for instant messaging and which are not is difficult, as future specifications may add additional payloads used for, or not used for, instant messaging; as such, the rules for which messages are eligible for carbons delivery is left as an implementation detail for servers. The following is a suggested set of rules a server MAY use, or it MAY use its own; in either case it SHOULD follow the general intent of these rules:</p>
<p>Possible delivery rules:
<ul>
<li>A &MESSAGE; is eligible for carbons delivery if it is of type "chat".</li>
<li>A &MESSAGE; is eligible for carbons delivery if it is of type "normal" and it contains a &lt;body&gt; element.</li>
<li>A &MESSAGE; is eligible for carbons delivery if it is of type "error" and sent in response to a &MESSAGE; that was itself eligible for carbons delivery (Note that as this would require message tracking and correlation on the server, it is unlikely to be generally appropriate for most implementations).</li>
<li>A &MESSAGE; is not eligible for carbons delivery if it is determined to have been sent by a MUC room or service, even if it would be otherwise eligible (this also includes private messages from MUC participants).</li>
<li>A &MESSAGE; is not eligible for carbons delivery if it does not meet any of these criteria.</li>
</ul>
</p>
<p>As this is a implementation detail of servers, clients MUST NOT rely on the server implementing a particular set of rules for which messages are eligible for Carbons delivery.</p>
<p>Future specifications may have more precise requirements on which messages need to be eligible for carbons delivery; such future specifications will provide their own discovery and negotiation mechanisms, such that a client negotiating Carbons using the protocol defined in this specification will cause the server to consider messages eligible for Carbons delivery based on the requirements described herein.</p>
<p>Note: previous versions of this specification limited eligible messages to those of type "chat" - however, this was generally found to be inadequate due to the proliferation of type "normal" messages used in instant messaging.</p>
</section1>
<example caption='Juliet sends Romeo an undirected message'><![CDATA[
<message xmlns='jabber:client'
from='juliet@capulet.example/balcony'
to='romeo@montague.example'
type='chat'>
<body>Wherefore art thou, Romeo?</body>
<thread>0e3141cd80894871a68e6fe6b1ec56fa</thread>
</message>]]></example>
<example caption='Message Forked to each of Romeo&apos;s Carbons-enabled resources'><![CDATA[
<message xmlns='jabber:client'
from='juliet@capulet.example/balcony'
to='romeo@montague.example/garden'
type='chat'>
<body>Wherefore art thou, Romeo?</body>
<thread>0e3141cd80894871a68e6fe6b1ec56fa</thread>
</message>
<message xmlns='jabber:client'
from='juliet@capulet.example/balcony'
to='romeo@montague.example/home'
type='chat'>
<body>Wherefore art thou, Romeo?</body>
<thread>0e3141cd80894871a68e6fe6b1ec56fa</thread>
</message>]]></example>
<p>The receiving server MUST deliver a copy to every Carbons-enabled resource, even if that resource normally would not receive &MESSAGE; stanzas addressed to the bare JID (e.g., resources which have broadcast &PRESENCE; with a negative priority). A Carbons-enabled resource MUST NOT receive more than one copy of the &MESSAGE;.</p>
</section1>
<section1 topic='Receiving Messages to the Full JID' anchor='inbound-full'>
<p>When the server receives a &MESSAGE; of type "chat" addressed to a full JID (localpart@domainpart/resourcepart), it delivers the &MESSAGE; according to <cite>RFC 6121</cite> § 8.5.3, and delivers a forwarded copy to each Carbons-enabled resource for the matching bare JID recipient.</p>
<section1 topic='Receiving Messages' anchor='inbound'>
<p>When the server receives a &MESSAGE; <link url='#which-messages'>eligible for carbons delivery</link> addressed to a client JID (either bare or full), it delivers the &MESSAGE; according to <cite>RFC 6121</cite> § 8.5.3, and then delivers a forwarded copy to each Carbons-enabled resource for the matching bare JID recipient that did not receive it under the RFC 6121 delivery rules.</p>
<p>Each forwarded copy is wrapped using &xep0297;. The wrapping message SHOULD maintain the same 'type' attribute value; the 'from' attribute MUST be the Carbons-enabled user's bare JID (e.g., "localpart@domainpart"); and the 'to' attribute MUST be the full JID of the resource receiving the copy. The content of the wrapping message MUST contain a &lt;received/&gt; element qualified by the namespace "urn:xmpp:carbons:2", which itself contains a &lt;forwarded/&gt; element qualified by the namespace "urn:xmpp:forward:0" that contains the original &MESSAGE;.</p>
<example caption='Juliet sends Romeo a directed message'><![CDATA[
@ -291,10 +286,10 @@
</message>
]]></example>
<p>The receiving server MUST NOT send a forwarded copy to the full JID the original &MESSAGE; stanza was addressed to, as that recipient receives the original &MESSAGE; stanza.</p>
<p>The receiving server MUST NOT send a forwarded copy to the client(s) the original &MESSAGE; stanza was addressed to, as these recipients receive the original &MESSAGE; stanza.</p>
</section1>
<section1 topic='Sending Messages' anchor='outbound'>
<p>When a client sends a &MESSAGE; of type "chat", its sending server delivers the &MESSAGE; according to <cite>RFC 6120</cite> and <cite>RFC 6121</cite>, and delivers a forwarded copy to each Carbons-enabled resource for the matching bare JID sender.</p>
<p>When a client sends a &MESSAGE; <link url='#which-messages'>eligible for carbons delivery</link>, its sending server delivers the &MESSAGE; according to <cite>RFC 6120</cite> and <cite>RFC 6121</cite>, and delivers a forwarded copy to each Carbons-enabled resource for the matching bare JID sender, excluding the sending client. Note that this happens irrespective of whether the sending client has carbons enabled.</p>
<p>Each forwarded copy is wrapped using &xep0297;. The wrapping message SHOULD maintain the same 'type' attribute value; the 'from' attribute MUST be the Carbons-enabled user's bare JID (e.g., "localpart@domainpart"); and the 'to' attribute SHOULD be the full JID of the resource receiving the copy. The content of the wrapping message MUST contain a &lt;sent/&gt; element qualified by the namespace "urn:xmpp:carbons:2", which itself contains a &lt;forwarded/&gt; qualified by the namespace "urn:xmpp:forward:0" that contains the original &MESSAGE; stanza.</p>
<example caption='Romeo responds to Juliet'><![CDATA[
<message xmlns='jabber:client'
@ -355,8 +350,8 @@
<p><strong>Note:</strong> if the private &MESSAGE; stanza is addressed to a bare JID, the receiving server still delivers it according to <cite>RFC 6121</cite>. This might result in a copy being delivered to each resource for the recipient, which effectively negates the behavior of the &lt;private/&gt; element for recipients.</p>
</section1>
<section1 topic='Business Rules' anchor='bizrules'>
<section2 topic='Handling Multiple Enable/Disalble Requests' anchor='bizrules-multi'>
<p>If a client is permitted to enable Carbons during its login session, the server MUST allow the client enable and disable the protocol multiple times within a session. The server SHOULD NOT treat multiple enable requests (without an intermediate disable request) as an error; it SHOULD simply return an IQ-result (if the protocol is already enabled) or an IQ-error (if the client is not permitted to enable Carbons) for any subsequent requests after the first. Similarly, the server SHOULD NOT treat multiple disable requests (without an intermediate enable request) as an error; it SHOULD return an IQ-result (if the protocols is already disabled) or an IQ-error (if the client's request failed previously) for any subsequent requests after the first.</p>
<section2 topic='Handling Multiple Enable/Disable Requests' anchor='bizrules-multi'>
<p>If a client is permitted to enable Carbons during its login session, the server MUST allow the client to enable and disable the protocol multiple times within a session. The server SHOULD NOT treat multiple enable requests (without an intermediate disable request) as an error; it SHOULD simply return an IQ-result (if the protocol is already enabled) or an IQ-error (if the client is not permitted to enable Carbons) for any subsequent requests after the first. Similarly, the server SHOULD NOT treat multiple disable requests (without an intermediate enable request) as an error; it SHOULD return an IQ-result (if the protocols is already disabled) or an IQ-error (if the client's request failed previously) for any subsequent requests after the first.</p>
</section2>
<section2 topic='Interaction with Chat States' anchor='bizrules-chatstates'>
<p>Note that &xep0085; recommends sending chat state

View File

@ -6,11 +6,14 @@
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>XMPP on Mobile Devices</title>
<abstract>This document provides background information for XMPP implementors concerned with mobile devices operating in a cellular network such as 3G.</abstract>
<title>Mobile Considerations</title>
<abstract>
This document provides background information for XMPP implementors
concerned with mobile devices operating on an LTE cellular network.
</abstract>
&LEGALNOTICE;
<number>0286</number>
<status>Deferred</status>
<status>Experimental</status>
<type>Informational</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -26,6 +29,24 @@
<email>dave.cridland@isode.com</email>
<jid>dave.cridland@isode.com</jid>
</author>
<author>
<firstname>Sam</firstname>
<surname>Whited</surname>
<email>sam@samwhited.com</email>
<jid>sam@samwhited.com</jid>
</author>
<revision>
<version>0.3</version>
<date>2015-07-24</date>
<initials>ssw</initials>
<remark><p>Include real world compression numbers and additional recommended reading.</p></remark>
</revision>
<revision>
<version>0.2</version>
<date>2015-07-22</date>
<initials>ssw</initials>
<remark><p>Overhaul to include LTE.</p></remark>
</revision>
<revision>
<version>0.1</version>
<date>2010-09-15</date>
@ -40,140 +61,181 @@
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>The use of XMPP on mobile devices is little understood, since few XMPP implementors have good mobile knowledge, and few mobile engineers have good XMPP knowledge. In addition, as the mobile landscape has changed, optimal protocol designs and usage patterns have also changed. This has led to the sub-optimal combination of a large amount of mostly undocumented lore, as well as several outdated concepts being discussed as fact.</p>
<p>This XEP aims to provide useful background knowledge of mobile handset behaviours, and essentially distills a number of conversations with experienced mobile engineers and XMPP implementors, providing useful background as general suggestions.</p>
<p>
XMPP as a protocol was designed before the wide spread adoption of mobile
devices, and is often cited as not being very mobile friendly as a result.
However, this mostly stems from undocumented lore and outdated notions of
how XMPP works. As the Internet and protocol design have changed to be more
accommodating for mobile, so has XMPP.
</p>
<p>
This XEP aims to provide useful background knowledge of mobile handset
behavior, and those considerations that client and server designers can
take to ensure that bandwidth and battery are used efficiently.
</p>
</section1>
<section1 topic='Overview' anchor='overview'>
<p>Mobile handsets typically have two constraints - power and bandwidth. The advent of 3G technology and beyond has tended to mean that bandwidth is radically higher, and comparable to broadband speeds - however many operators still charge based on transferred data, hence bandwidth remains an important issue for cost purposes.</p>
<p>The major cost of power in the handset for our purposes is the radio - here, too, bandwidth plays a part, but as this document will show, the time the radio is forced to be available to receive also costs substantially.</p>
<p>Whilst this document refers to &rfc3920;, implementors are advised to take note of &rfc6120;.</p>
<p>
The two major constraints on mobile devices are power and bandwidth. With
the wide spread proliferation of 3G and LTE technologies, mobile bandwidth
and speeds have become broadly comparable to broadband. However, they are
still relatively expensive compared to traditional wired networks, and
should therefore still be considered. This XEP mostly focuses on LTE as it
already has a very wide deployment and will only continue to further
replace 3G technologies.
</p>
</section1>
<section1 topic='Compression'>
<p>XMPP is known to compress well. Both TLS, part of &xmppcore;, and &xep0138; can provide access to the DEFLATE codec (<span class='ref'><link url='http://tools.ietf.org/html/rfc1951'>RFC 1951</link></span> <note>RFC 1951 DEFLATE Compressed Data Format Specification version 1.3
&lt;<link url='http://tools.ietf.org/html/rfc1951'>http://tools.ietf.org/html/rfc1951</link>&gt;.</note>), which provides access to simple stream compression.</p>
<p>Compression ratios vary with usage, however, typical usage by a general client appears to show a 20% ratio (an 80% reduction in bandwidth) in longer sessions<note>Fixed-purpose clients, such as the Buddycloud client, do see even lower ratios, approaching 10%.</note>. Server implementors should note that there is a substantial memory cost per codec of 300KB assuming maximum settings - this may be dramatically reduced by reducing the memory level and window bits of the implementation - lowering memory level primarily causes increased CPU usage, whereas lowering the window bits directly degrade compression.</p>
<p>At an exemplary point in one experiment, the author found the following figures<note>The compression ratio is here given as Original/Compressed, hence a 100% compression ratio is no compression at all, and 0% would represent infinite compression.</note>:</p>
<table>
<tr>
<th>Window Bits</th>
<th>Compression Ratio (approx)</th>
</tr>
<tr>
<td>15</td>
<td>20%</td>
</tr>
<tr>
<td>14</td>
<td>22%</td>
</tr>
<tr>
<td>13</td>
<td>25%</td>
</tr>
<tr>
<td>12</td>
<td>30%</td>
</tr>
<tr>
<td>11</td>
<td>38%</td>
</tr>
<tr>
<td>10</td>
<td>43%</td>
</tr>
<tr>
<td>9</td>
<td>60%</td>
</tr>
</table>
<p>Although there is an equal cost for the mobile device to compress, it is considered that the compression codec memory and CPU costs - while certainly translating into power cost - are outweighed by two factors. Firstly, they're likely to reduce the transmission cost by a greater amount, and secondly they will also reduce the encryption cost in TLS.</p>
<p>Care, however, should be taken not to use XEP-0138 compression when TLS compression is in effect.</p>
<section1 topic='Compression' anchor='compression'>
<p>
XML, and by extension XMPP, is known to be highly compressible.
Compression of XMPP data can be achieved with the DEFLATE algorithm
(&rfc1951;) via TLS compression (&rfc3749;) or &xep0138; (which also
supports other compression algorithms). While the security implications of
stream compression are beyond the scope of this document (See the
aforementioned RFC or XEP for more info), the author does not recommend
using TLS compression with XMPP (or in general). If compression must be
used, stream level compression should be implemented instead, and the
compressed stream should have a full flush performed on stanza boundaries
to help prevent a class of chosen plaintext attacks which can cause data
leakage in compressed streams. While this may mitigate some of the benefits
of compression by raising compression ratios, in a large, real world
deployment at HipChat, network traffic was still observed to decrease by a
factor of 0.58 when enabling &xep0138; with ZLIB compression!
</p>
<p>
While the CPU cost of compression may directly translate to higher power
usage, it is vastly outweighed by the benefits of reduced network
utilization, especially on modern LTE networks which use a great deal more
power per bit than 3G networks as will be seen later in this document.
However, CPU usage is also not guaranteed to rise due to compression. In
the aforementioned deployment of stream compression, a <em>decrease</em> in
CPU utilization by a factor of 0.60 was observed due to the fact that there
were fewer packets that needed to be handled by the OS (which also takes
CPU time), and, potentially more importantly, less data that needed to be
TLS-encrypted (which is a much more CPU-expensive operation than
compression). Therefore CPU time spent on compression (for ZLIB, at least;
other algorithms were not tested) should be considered negligable.
</p>
<p>
Supporting compression and flushing on stanza boundaries is highly
recommended.
</p>
</section1>
<section1 topic='Radio Power'>
<p>Mobile handsets have a number of levels for radio activity. 3G radios can be either Idle, or else in an increasingly capable - and increasingly power-hungry - series of levels, through FACH to DCH.</p>
<p>For the purposes of investigating this, power consumption (or rather battery depletion rate, as current) and timeouts where measured on the 3UK network, with a Nokia E71, using the Energy Profiler. A "typical handset" mentioned here has a 1000mAh battery - some smartphones have up to 1500mAh. Note that all timeouts are under the control of the network operator, not the handset or application.</p>
<section2 topic='Idle'>
<p>Idle state is when the radio is neither receiving nor transmitting. It may have live (although silent) TCP connections. The cost is low. There is also a PCH level, which is similarly low-power, and again is only used when the radio is silent.</p>
<p>The current here was measured as 8mA - likely affected more by the energy profiler than much else.</p>
</section2>
<section2 topic='FACH'>
<p>FACH uses a shared channel for low-bandwidth communications. Packet sizes must be small - around 128 octets maximum, although this is operator controlled. Raising to this state takes around 2.5 seconds before the data can flow - although the power cost rises instantly - and after the session has returned to silence, it will remain at FACH level for some time.</p>
<p>Note that this threshold includes the overheads from TCP and TLS, which are 52 and 5 octets respectively, leaving around 70 octets for the payload data.</p>
<p>Here, the current was measured as 140mA, and a timeout of 8 seconds - this timeout is at the lower end of the expected range, which could be up to around 2 minutes. On a typical handset, this will exhaust the battery in around 7 hours.</p>
</section2>
<section2 topic='DCH'>
<p>DCH uses a dedicated channel for high bandwidth communications. Again, raising to this state takes 2.5 seconds at the DCH power level, and there is a timeout before dropping back. Some operators will drop back to FACH for the duration fo the FACH timeout - others will drop back to Idle/PCH.</p>
<p>Sending more than the FACH threshold will raise the radio all the way to DCH - taking, again, 2.5 seconds.</p>
<p>The measurements here were 380mA and 8 seconds - this is sufficient to flatten a typical handset battery in less than 3 hours, and the figures are considered normal.</p>
</section2>
<p>Transmission of data can use up to 2W<note>The author's hazy recollection of P=IV suggests around a 570mA current</note>, and raising the level itself takes between 2 and 3 seconds to take effect - during which time the handset cannot receive or transmit, but still incurs the power cost. There are packets sent from and to the handset during this time.</p>
<p>Experimentation suggests that uncompressed XMPP will never trigger the FACH state, leaping directly into the more costly DCH state. However, compression does make FACH possible, if rare.</p>
<section1 topic='Power Consumption' anchor='power'>
<p>
While the wide spread adoption of LTE has dramatically increased available
bandwidth on mobile devices, it has also increased power consumption.
According to one study, early LTE devices consumed 5&#x2013;20% more power
than their 3G counterparts
<note>LTE Smartphone measurements &lt;<link url='http://networks.nokia.com/system/files/document/lte_measurements_final.pdf'>http://networks.nokia.com/system/files/document/lte_measurements_final.pdf</link>&gt;</note>.
On some networks that support the legacy SVLTE (Simultaneous Voice and LTE)
instead of the more modern VoLTE (Voice Over LTE) standard, or even CSFB
(Circuit-switched fallback) this number would (presumably) be even higher.
</p>
<p>
XMPP server and client implementers, bearing this increased power usage in
mind, and knowing a bit about how LTE radios work, can optimize their
traffic to minimize network usage. For the downlink, LTE user equipment
(UE) utilizes Orthogonal Frequency Division Multiplexing (OFDM), which is
somewhat inefficient
<note>A Close Examination of Performance and Power Characteristics of 4G LTE Networks &lt;<link url='http://www.cs.columbia.edu/~lierranli/coms6998-7Spring2014/papers/rrclte_mobisys2012.pdf'>http://www.cs.columbia.edu/~lierranli/coms6998-7Spring2014/papers/rrclte_mobisys2012.pdf</link>&gt;</note>.
On the uplink side a different technology, Single-carrier frequency
division multiple access (SC-FDMA) is used, which is slightly more
efficient than traditional (non linearly-precoded) OFDM, slightly
offsetting the fact that broadcasting requires more power than receiving.
LTE UE also implements a Discontinuous reception (DRX) mode in which the
hardware can sleep until it is woken by a paging message or is needed to
perform some task. LTE radios have two power modes: RRC_CONNECTED and
RRC_IDLE. DRX is supported in both of these power modes. By attempting to
minimize the time which the LTE UE state machine spends in the
RCC_CONNECTED state, and maximize the time it stays in the DRX state (for
RCC_CONNECTED and RRC_IDLE), we can increase battery life without degrading
the XMPP experience. To do so, the following rules should be observed:
</p>
<section2 topic='Transmit no data'>
<p>
Whenever possible, data that is not strictly needed should not be
transmitted (by the server or client). Supporting &xep0352; is highly
recommended. Most importantly, XMPP pings should be kept as far apart as
possible and only used when necessary. Server operators are encouraged to
set high ping timeouts, and client implementors are advised to only send
pings when absolutely necessary to prevent the server from closing the
socket.
</p>
</section2>
<section2 topic='Transmit as much data as you can at once'>
<p>
If one is on 3G, transmitting a small amount of data will cause the radio
to enter FACH mode which is significantly cheaper than its high power
mode. On LTE radios, however, transmitting small amounts of data is
vastly more expensive per bit due to the significantly higher tail-times
(the time it takes for the radio to change state). On LTE radios, one
should transmit as much data as possible when the radio is already on
(eg. by placing messages in a send queue and executing the queue as a
batch). Similarly, when data is being received the radio is already in a
high power state and therefore any data that needs to be sent should be.
</p>
<p>
These rules also apply to server operators: If you receive data, the
phones radio is already on therefore you should send anything you have.
Otherwise, batching data to be sent and sending it all at once (and as
much as possible) will help reduce power consumption.
</p>
</section2>
</section1>
<section1 topic='Conclusions'>
<p>As with anything, there are no hard and fast rules. If there were, they might look like these. First, for devices:</p>
<dl>
<di>
<dt>Transmit no data.</dt>
<dd>Transmitting costs significant power, and moreover raises the radio state. Not transmitting will allow it to maximize the time spent in the low-cost Idle state.</dd>
</di>
<di>
<dt>If you must transmit, then transmit only a small volume.</dt>
<dd>If there is only a small amount of data transmitted - less than 128 octets typically - the radio will only raise to FACH, which is significantly cheaper than DCH.</dd>
</di>
<di>
<dt>If you must transmit, then compress as hard as possible.</dt>
<dd>Since individual octets have an associate power - and often financial - cost, it's worth maximizing the compression algorithm, even if the volume of traffic will raise to DCH.</dd>
</di>
<di>
<dt>If you have transmit a lot, then do a lot</dt>
<dd>If the radio is raised to DCH anyway, then you may as well go fetch that avatar you were missing, since you're chewing through power anyway.</dd>
</di>
<di>
<dt>If you receive, then transmit</dt>
<dd>If your peer raises the radio state, you may as well use it.</dd>
</di>
</dl>
<p>And for servers, similar rules apply:</p>
<dl>
<di>
<dt>Send no data.</dt>
<dd>Sending data will cause the handset to be raised out of Idle. This immediately costs massively higher power.</dd>
</di>
<di>
<dt>If you must send, send tiny bits.</dt>
<dd>Sending small enough data maximizes the likelyhood that the devices radio will only be raised to FACH levels.</dd>
</di>
<di>
<dt>If you receive, then send anything you have.</dt>
<dd>Receiving data indicates that the radio is active - it'll stay active for some time, so sending data doesn't incur the overhead of raising the radio state, and won't increase power drain on the handset.</dd>
</di>
<di>
<dt>If you must send when not receiving, send plenty.</dt>
<dd>Sending data will raise the radio's state - unless you can tell this will only raise it to FACH, it's worth sending as much as possible.</dd>
</di>
</dl>
<p>Finally, protocol designers should aim to minimize any responses required from the handset, and ensure keepalive traffic, if any, fits inside FACH wherever possible.</p>
</section1>
<section1 topic='Notable Extensions'>
<p>This section provides pointers to other documents which may be of interest to those developing mobile clients, or considering support for them in servers.</p>
<p>&xep0138; provides application stream level compression, useful if the device TLS stack does not support TLS-based compression.</p>
<p>&xep0115; provides a mechanism for caching, and hence eliding, the disco#info requests needed to negotiate optional features.</p>
<p>&xep0237; provides a relatively widely deployed extension for reducing the roster fetch bandwidth, in most cases reducing it to a simple affirmation that the client has the current roster. This saves not only bandwidth, but also reduces local storage writes.</p>
<p>&xep0198; provides session resumption over TCP, enabling a client to handle the case where the coverage is patchy. The &lt;r/> and &lt;a/> elements also provide a keepalive facility in a small number of octets.</p>
<p>&xep0273; provides a mechanism which, amongst other things, would allow a presence "hush", buffering presence during certain states.</p>
<section1 topic='Notable Extensions' anchor='xeps'>
<p>
This section provides pointers to other documents which may be of interest
to those developing mobile clients, or considering support for them in
servers.
</p>
<p>&xep0138; provides stream level compression.</p>
<p>&xep0322; allows XMPP streams to use the EXI XML format.</p>
<p>
&xep0115; provides a mechanism for caching, and hence eliding, the
disco#info requests needed to negotiate optional features.
</p>
<p>
&xep0237; provides a relatively widely deployed extension for reducing
roster fetch sizes.
</p>
<p>
&xep0198; allows the client to send and receive smaller keep-alive
messages, and resume existing sessions without the full handshake. Useful
on unstable connections.
</p>
<p>
&xep0357; implements push notifications (third party message delivery),
which are often used on mobile devices and highly optimized to conserve
battery. Push notifications also allow delivery of notifications to mobile
clients that are currently offline (eg. in an XEP-0198 "zombie" state).
</p>
<p>
&xep0313; lets clients fetch messages which they missed (eg. due to poor
mobile coverage and a flaky network connection).
</p>
</section1>
<section1 topic='Acknowledgements' anchor='acks'>
<p>The author is not a mobile expert, and relied on the knowledge and patient help of several others. In particular, thanks are due to Jussi Laako, Markku Vampari, and Markus Isomaki of Nokia, and Simon Tennant of Buddycloud.</p>
<p>The attribution of any mistakes herein is zealously guarded by the author, however.</p>
<p>
This XEP was originally written by Dave Cridland, and parts of his original
work were used in this rewrite. Thanks to Atlassian for allowing me to
release hard numbers from their XMPP compression deployment.
</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>This document does not discuss a protocol, thus introduces no new security considerations.</p>
<p>This document introduces no new security considerations.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>None.</p>
<p>
This document requires no interaction with the Internet Assigned Numbers
Authority (IANA).
</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<p>None.</p>
<p>
No namespaces or parameters need to be registered with the XMPP Registrar
as a result of this document.
</p>
</section1>
</xep>

View File

@ -13,8 +13,7 @@
sessions</abstract>
&LEGALNOTICE;
<number>0293</number>
<status>Proposed</status>
<lastcall>2015-01-20</lastcall>
<status>Draft</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -22,6 +21,9 @@
<spec>XEP-0167</spec>
<spec>RFC 4585</spec>
</dependencies>
<schemaloc>
<url>http://xmpp.org/schemas/jingle-apps-rtp-rtcp-fb.xsd</url>
</schemaloc>
<author>
<firstname>Olivier</firstname>
<surname>Crête</surname>
@ -29,6 +31,12 @@
<jid>olivier.crete@collabora.co.uk</jid>
</author>
<discuss>jingle</discuss>
<revision>
<version>1.0</version>
<date>2015-08-11</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Advanced to Draft per a vote of the XMPP Council.</p></remark>
</revision>
<revision>
<version>0.3</version>
<date>2015-04-29</date>
@ -139,7 +147,7 @@ milliseconds for this media session. It corresponds to the
<section1 topic='Negotiation' anchor='negotiation'>
<p>Feedback messages are negotiated along the codecs. They follow
<p>Feedback messages are negotiated along side the codecs. They follow
the same Offer/Answer mechanism based on SDP Offer/Answer. The
initiator signals which feedback messages it wants to send or
receive in the the &lt;session-initiate/&gt; iq stanza. If the

View File

@ -12,8 +12,7 @@
with Jingle RTP sessions</abstract>
&LEGALNOTICE;
<number>0294</number>
<status>Proposed</status>
<lastcall>2015-01-20</lastcall>
<status>Draft</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -21,6 +20,9 @@
<spec>XEP-0167</spec>
<spec>RFC 5285</spec>
</dependencies>
<schemaloc>
<url>http://xmpp.org/schemas/jingle-apps-rtp-rtp-hdrext.xsd</url>
</schemaloc>
<author>
<firstname>Olivier</firstname>
<surname>Crête</surname>
@ -28,6 +30,12 @@
<jid>olivier.crete@collabora.co.uk</jid>
</author>
<discuss>jingle</discuss>
<revision>
<version>1.0</version>
<date>2015-08-11</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Advanced to Draft per a vote of the XMPP Council.</p></remark>
</revision>
<revision>
<version>0.2</version>
<date>2015-03-25</date>

View File

@ -27,12 +27,23 @@
</schemaloc>
&mwild;
&ksmith;
<revision>
<version>0.4.1</version>
<date>2015-09-29</date>
<initials>XEP Editor (mam)</initials>
<remark>
<p>Fix Example #9 from &lt;/message/&gt; to &lt;/iq&gt; (Florian Schmaus)</p>
<p>Add missing jabber:client namespace in Example #2 (Christian Schudt)</p>
</remark>
</revision>
<revision>
<version>0.4</version>
<date>2015-01-23</date>
<date>2015-09-21</date>
<initials>ks/mw</initials>
<remark><p>Switch the sentinel message back to the iq result.
Various small fixes to the document.</p></remark>
<remark>
<p>Switch the sentinel message back to the iq result.</p>
<p>Various small fixes to the document.</p>
</remark>
</revision>
<revision>
<version>0.3</version>
@ -151,38 +162,40 @@
<p>A query consists of an &IQ; stanza of type='set' addressed to the account or server entity hosting
the archive, with a 'query' payload. On receiving the query, the server pushes to the client a
series of messages from the archive that match the client's given criteria, and finally returns
a &MESSAGE; with a &lt;fin/&gt; tag to indicate that the query is completed.</p>
the &IQ; result to indicate that the query is completed.</p>
<p>The final &MESSAGE; response MUST include an RSM &lt;set/&gt; element indicating the
UID of the first and last message of the (possibly limited) result set. This
allows clients to accurately page through messages.</p>
<example caption='A user queries their archive for messages'><![CDATA[
<iq type='set' id='juliet1'>
<query xmlns='urn:xmpp:mam:0' queryid='f27' />
<query xmlns='urn:xmpp:mam:1' queryid='f27' />
</iq>]]></example>
<example caption='Their server accepts the query'><![CDATA[
<iq type='result' id='juliet1'/>]]></example>
<example caption='Their server sends the matching messages'><![CDATA[
<message from="witch@shakespeare.lit" to="macbeth@shakespeare.lit">
<body>Hail to thee</body>
<message id='aeb213' to='juliet@capulet.lit/chamber'>
<result xmlns='urn:xmpp:mam:1' queryid='f27' id='28482-98726-73623'>
<forwarded xmlns='urn:xmpp:forward:0'>
<delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>
<message xmlns='jabber:client' from="witch@shakespeare.lit" to="macbeth@shakespeare.lit">
<body>Hail to thee</body>
</message>
</forwarded>
</result>
</message>]]></example>
<example caption='Server returns the message sentinel'><![CDATA[
<message>
<fin xmlns='urn:xmpp:mam:0' queryid='f27' />
</message>]]></example>
<p>To ensure that the client knows when the results are complete, the server MUST send a &lt;fin&gt; message. The client can optionally include a 'queryid' attribute in their query, which allows the client to match results to their initiating query, and if present in the client's query the server MUST include it in the &lt;fin&gt; response.</p>
<example caption='Server returns the result IQ to signal the end'><![CDATA[
<iq type='result' id='juliet1'/>]]></example>
<p>To ensure that the client knows when the results are complete, the server MUST send the &IQ; result after the last message retrieved from the archive. The client can optionally include a 'queryid' attribute in their query, which allows the client to match results to their initiating query.</p>
<p>When querying a pubsub node's archive, the 'node' attribute is added to the &lt;query&gt; element.</p>
<example caption="A user queries a pubsub node's archive for messages"><![CDATA[
<iq to='pubsub.shakespeare.lit' type='set' id='juliet1'>
<query xmlns='urn:xmpp:mam:0' queryid='f28' node='fdp/submitted/capulet.lit/sonnets'/>
<query xmlns='urn:xmpp:mam:1' queryid='f28' node='fdp/submitted/capulet.lit/sonnets'/>
</iq>
]]></example>
<section2 topic='Filtering results' anchor='filter'>
<p>By default all messages match a query, and filters are used to request a subset of the archived
messages. Filters are specified in a &xep0004; data form included with the query. The hidden FORM_TYPE field
MUST be set to this protocol's namespace, 'urn:xmpp:mam:0'. Three further fields are defined by this
MUST be set to this protocol's namespace, 'urn:xmpp:mam:1'. Three further fields are defined by this
XEP and MUST be supported by servers, though all of them are optional for the client. These fields are:
<ul>
<li>start</li>
@ -201,10 +214,10 @@
regardless of the to/from addresses on each message.</p>
<example caption='Querying for all messages to/from a particular JID'><![CDATA[
<iq type='set' id='juliet1'>
<query xmlns='urn:xmpp:mam:0'>
<query xmlns='urn:xmpp:mam:1'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>urn:xmpp:mam:0</value>
<value>urn:xmpp:mam:1</value>
</field>
<field var='with'>
<value>juliet@capulet.lit</value>
@ -233,10 +246,10 @@
date/time of the most recent message stored in the archive.</p>
<example caption='Querying the archive for all messages in a certain timespan'><![CDATA[
<iq type='set' id='juliet1'>
<query xmlns='urn:xmpp:mam:0'>
<query xmlns='urn:xmpp:mam:1'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>urn:xmpp:mam:0</value>
<value>urn:xmpp:mam:1</value>
</field>
<field var='start'>
<value>2010-06-07T00:00:00Z</value>
@ -250,10 +263,10 @@
]]></example>
<example caption='Querying the archive for all messages after a certain time'><![CDATA[
<iq type='set' id='juliet1'>
<query xmlns='urn:xmpp:mam:0'>
<query xmlns='urn:xmpp:mam:1'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>urn:xmpp:mam:0</value>
<value>urn:xmpp:mam:1</value>
</field>
<field var='start'>
<value>2010-08-07T00:00:00Z</value>
@ -271,10 +284,10 @@
stanzas stored in the archive.</p>
<example caption='A query using Result Set Management'><![CDATA[
<iq type='set' id='q29302'>
<query xmlns='urn:xmpp:mam:0'>
<query xmlns='urn:xmpp:mam:1'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>urn:xmpp:mam:0</value>
<value>urn:xmpp:mam:1</value>
</field>
<field var='start'>
<value>2010-08-07T00:00:00Z</value>
@ -290,17 +303,16 @@
pushed to a client in one request. Whether or not the client query included a &lt;set/&gt; element, the server MAY simply return
its limited results, modifying the &lt;set/&gt; element it returns appropriately.</p>
<example caption='Server responds to client with limited results using RSM'><![CDATA[
<iq type='result' id='q29302'/>
<!-- result messages -->
<message>
<fin xmlns='urn:xmpp:mam:0'>
<iq type='result' id='q29302'>
<fin xmlns='urn:xmpp:mam:1'>
<set xmlns='http://jabber.org/protocol/rsm'>
<first index='0'>28482-98726-73623</first>
<last>09af3-cc343-b409f</last>
<count>20</count>
</set>
</fin>
</message>
</iq>
]]></example>
<p>The &lt;first&gt; and &lt;last&gt; elements specify the UID of the first and last returned
results (not necessarily of all the messages that matched the query, if the results have been limited).</p>
@ -316,9 +328,9 @@
from the previous query.</p>
<example caption='A page query using Result Set Management'><![CDATA[
<iq type='set' id='q29303'>
<query xmlns='urn:xmpp:mam:0'>
<query xmlns='urn:xmpp:mam:1'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'><value>urn:xmpp:mam:0</value></field>>
<field var='FORM_TYPE' type='hidden'><value>urn:xmpp:mam:1</value></field>>
<field var='start'><value>2010-08-07T00:00:00Z</value></field>
</x>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -329,34 +341,33 @@
</iq>
]]></example>
<p>Note: There is no concept of an "open query", and servers MUST be prepared to receive arbitrary page requests at any time.</p>
<p>When the results returned by the server are complete (that is: when they are the last page of the result set), the server MUST include a 'complete' attribute on the &lt;fin&gt; element, with a value of 'true'. If it is not the last page of the result set, the server MUST either omit the 'complete' attribute, or give it a value of 'false'.</p>
<p>When the results returned by the server are complete (that is: when they are the last page of the result set), the server MUST include a 'complete' attribute in the &IQ; result, with a value of 'true'. If it is not the last page of the result set, the server MUST either omit the 'complete' attribute, or give it a value of 'false'.</p>
<example caption='Server completes a result with the last page of messages'><![CDATA[
<iq type='result' id='u29303'/>
<!-- result messages -->
<message>
<fin xmlns='urn:xmpp:mam:0' complete='true'>
<iq type='result' id='u29303'>
<fin xmlns='urn:xmpp:mam:1' complete='true'>
<set xmlns='http://jabber.org/protocol/rsm'>
<first index='0'>23452-4534-1</first>
<last>390-2342-22</last>
<count>16</count>
</set>
</fin>
</message>
</iq>
]]></example>
<p>Sometimes (e.g. due to network or storage partitioning, or other transient errors) the server might return results to a client that are unstable (e.g. they might later change in sequence or content). In such a situation the server MUST stamp the &lt;fin&gt; element with a 'stable' attribute with a value of 'false'. If the server knows that the data it's serving are stable it MUST either stamp a 'stable' attribute with a value of 'true', or no such attribute. An example of when unstable might legitimately be returned is if the MAM service uses a clustered data store and a query covers a time period for which the data store has not yet converged; it the server could return best-guess results and tell the client that they may be unstable. A client SHOULD NOT cache unstable results long-term without later confirming (by reissuing appropriate queries) that they have become stable.</p>
<p>Sometimes (e.g. due to network or storage partitioning, or other transient errors) the server might return results to a client that are unstable (e.g. they might later change in sequence or content). In such a situation the server MUST stamp the &IQ; result with a 'stable' attribute with a value of 'false'. If the server knows that the data it's serving are stable it MUST either stamp a 'stable' attribute with a value of 'true', or no such attribute. An example of when unstable might legitimately be returned is if the MAM service uses a clustered data store and a query covers a time period for which the data store has not yet converged; it the server could return best-guess results and tell the client that they may be unstable. A client SHOULD NOT cache unstable results long-term without later confirming (by reissuing appropriate queries) that they have become stable.</p>
</section3>
<section3 topic='Retrieving form fields' anchor='query-form'>
<p>In order for the client find out about additional fields the server might support, it can send an iq stanza of type='get' addressed to the archive like this:</p>
<example><![CDATA[
<iq type='get' id='form1'>
<query xmlns='urn:xmpp:mam:0'/>
<query xmlns='urn:xmpp:mam:1'/>
</iq>
<iq type='result' id='form1'>
<query xmlns='urn:xmpp:mam:0'>
<query xmlns='urn:xmpp:mam:1'>
<x xmlns='jabber:x:data' type='form'>
<field type='hidden' var='FORM_TYPE'>
<value>urn:xmpp:mam:0</value>
<value>urn:xmpp:mam:1</value>
</field>
<field type='jid-single' var='with'/>
<field type='text-single' var='start'/>
@ -370,10 +381,10 @@
<p>If it understands any of the additional fields, it can use them in subsequent queries.</p>
<example><![CDATA[
<iq type='set' id='query4'>
<query xmlns='urn:xmpp:mam:0'>
<query xmlns='urn:xmpp:mam:1'>
<x xmlns='jabber:x:data' type='submit'>
<field type='hidden' var='FORM_TYPE'>
<value>urn:xmpp:mam:0</value>
<value>urn:xmpp:mam:1</value>
</field>
<field type='text-single' var='urn:example:xmpp:free-text-search'>
<value>Where arth thou, my Juliet?</value>
@ -406,7 +417,7 @@
</p>
<example caption='Server returns two matching messages'><![CDATA[
<message id='aeb213' to='juliet@capulet.lit/chamber'>
<result xmlns='urn:xmpp:mam:0' queryid='f27' id='28482-98726-73623'>
<result xmlns='urn:xmpp:mam:1' queryid='f27' id='28482-98726-73623'>
<forwarded xmlns='urn:xmpp:forward:0'>
<delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>
<message xmlns='jabber:client'
@ -420,7 +431,7 @@
</message>
<message id='aeb214' to='juliet@capulet.lit/chamber'>
<result xmlns='urn:xmpp:mam:0' queryid='f27' id='5d398-28273-f7382'>
<result xmlns='urn:xmpp:mam:1' queryid='f27' id='5d398-28273-f7382'>
<forwarded xmlns='urn:xmpp:forward:0'>
<delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:09:32Z'/>
<message xmlns='jabber:client'
@ -453,10 +464,10 @@
<p>A MUC archive MUST NOT include 'private message' results (those sent directly between occupants, not shared in the room) in the results</p>
</section3>
<section3 topic="Pubsub Archives">
<p>A PubSub service offering MAM SHOULD store each of the items published to each node. When responding to MAM requests it MUST construct the message stanza within the &lt;forwarded&gt; element in the same manner as the notifications sent to subscribers for the item, except that specifying the 'from' 'to' and 'id' attributes are OPTIONAL. Pubsub items must be returned one per message stanza (i.e. there MUST NOT be multiple &lt;item&gt; elemetns within the &lt;items&gt; element).</p>
<p>A PubSub service offering MAM SHOULD store each of the items published to each node. When responding to MAM requests it MUST construct the message stanza within the &lt;forwarded&gt; element in the same manner as the notifications sent to subscribers for the item, except that specifying the 'from' 'to' and 'id' attributes are OPTIONAL. Pubsub items must be returned one per message stanza (i.e. there MUST NOT be multiple &lt;item&gt; elements within the &lt;items&gt; element).</p>
<example caption='Server returns a pubsub messages'><![CDATA[
<message id='iasd208' to='juliet@capulet.lit/chamber'>
<result xmlns='urn:xmpp:mam:0' queryid='g28' id='28482-20987-73623'>
<result xmlns='urn:xmpp:mam:1' queryid='g28' id='28482-20987-73623'>
<forwarded xmlns='urn:xmpp:forward:0'>
<delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>
<message xmlns="jabber:client">
@ -507,7 +518,7 @@
</ul>
<example caption='Retrieving archiving preferences'><![CDATA[
<iq type='get' id='juliet2'>
<prefs xmlns='urn:xmpp:mam:0'/>
<prefs xmlns='urn:xmpp:mam:1'/>
</iq>
]]></example>
@ -517,7 +528,7 @@
<example caption='Server responds with current preferences'><![CDATA[
<iq type='result' id='juliet2'>
<prefs xmlns='urn:xmpp:mam:0' default='roster'>
<prefs xmlns='urn:xmpp:mam:1' default='roster'>
<always/>
<never/>
</prefs>
@ -539,7 +550,7 @@
<example caption='Updating archiving preferences'><![CDATA[
<iq type='set' id='juliet3'>
<prefs xmlns='urn:xmpp:mam:0' default='roster'>
<prefs xmlns='urn:xmpp:mam:1' default='roster'>
<always>
<jid>romeo@montague.lit</jid>
</always>
@ -553,7 +564,7 @@
MAY be different to the preferences sent by the client):</p>
<example caption='Server responds with updated preferences'><![CDATA[
<iq type='result' id='juliet3'>
<prefs xmlns='urn:xmpp:mam:0' default='roster'>
<prefs xmlns='urn:xmpp:mam:1' default='roster'>
<always>
<jid>romeo@montague.lit</jid>
</always>
@ -645,7 +656,7 @@
<section1 topic='Determining support' anchor='support'>
<p>If a server or other entity hosts archives and supports MAM queries, it MUST advertise
the 'urn:xmpp:mam:0' feature in response to &xep0030; requests made to archiving JIDs
the 'urn:xmpp:mam:1' feature in response to &xep0030; requests made to archiving JIDs
(i.e. JIDs hosting an archive, such as users' bare JIDs):
</p>
<example caption='Client queries for server features'><![CDATA[
@ -658,7 +669,7 @@
<iq type='result' id='disco1' from='juliet@capulet.lit' to='juliet@capulet.lit/balcony'>
<query xmlns='http://jabber.org/protocol/disco#info'>
...
<feature var='urn:xmpp:mam:0'/>
<feature var='urn:xmpp:mam:1'/>
...
</query>
</iq>
@ -689,7 +700,7 @@
</section1>
<section1 topic='Acknowledgements' anchor='acks'>
<p>Many thanks to Dave Cridland, Kim Alvefur, Yann Leboulanger and Lance Stout
<p>Many thanks to Dave Cridland, Kim Alvefur, Yann Leboulanger, Evgeny Khramtsov, Florian Schmaus and Lance Stout
for their input and feedback on this specification.</p>
</section1>

View File

@ -10,7 +10,8 @@
<abstract>This specification defines how to use DTLS-SRTP (RFC 5763) in the Jingle application type for the Real-time Transport Protocol (RTP) as a way to negotiate media path key agreement for secure RTP in one-to-one media sessions.</abstract>
&LEGALNOTICE;
<number>0320</number>
<status>Experimental</status>
<status>Proposed</status>
<lastcall>2015-09-07</lastcall>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -32,6 +33,26 @@
-->
<discuss>jingle</discuss>
&fippo;
<revision>
<version>0.3.1</version>
<date>2015-10-15</date>
<initials>ph</initials>
<remark>
<ul>
<li>Noted that whitespace is not significant in examples.</li>
</ul>
</remark>
</revision>
<revision>
<version>0.3</version>
<date>2015-09-28</date>
<initials>ph</initials>
<remark>
<ul>
<li>Clarified that holdconn setup role is not mapped.</li>
</ul>
</remark>
</revision>
<revision>
<version>0.2</version>
<date>2013-10-22</date>
@ -66,7 +87,7 @@
<section1 topic='Protocol' anchor='protocol'>
<p>&xep0167; recommends the use of the Secure Real-time Transport Protocol (SRTP) for end-to-end encryption of RTP sessions negotiated using &xep0166;. &rfc5763; provides an approach to establish a Secure Real-time Transport Protocol (SRTP) security context using the Datagram Transport Layer Security (DTLS) protocol. A mechanism of transporting the fingerprint attribute that identifies the key that will be presented during the DTLS handshake in Jingle is defined herein. Inclusion of this information is OPTIONAL in both SIP/SDP and Jingle.</p>
<p>Note that while this specification only describes the use in the context of DTLS-SRTP, the fingerprint transported can be used in other contexts like for example establishing connections using SCTP over DTLS.</p>
<p>Note that while this specification only describes the use in the context of DTLS-SRTP, the fingerprint transported can be used in other contexts like for example establishing connections using SCTP over DTLS as described in &xep0343;.</p>
<p>The SDP format (defined in &rfc4572;) is shown below.</p>
<code>
a=fingerprint:hash-func fingerprint
@ -79,13 +100,14 @@ a=fingerprint:sha-256 02:1A:CC:54:27:AB:EB:9C:53:3F:3E:4B:65:2E:7D:46:3F:54:42:C
<code>
a=setup:role
</code>
<p>Note that no mapping for the 'holdconn' role is defined herein.</p>
<p>These SDP attributes can be translated into Jingle as a &lt;fingerprint/&gt; element qualified by the 'urn:xmpp:jingle:apps:dtls:0' namespace, as shown below.</p>
<code><![CDATA[
<fingerprint xmlns='urn:xmpp:jingle:apps:dtls:0' hash='hash-func' setup='role'>
fingerprint
</fingerprint>
]]></code>
<p>An example follows.</p>
<p>An example follows. Note that the whitespace would not appear in actual XML content.</p>
<code><![CDATA[
<fingerprint xmlns='urn:xmpp:jingle:apps:dtls:0' hash='sha-256' setup='actpass'>
02:1A:CC:54:27:AB:EB:9C:53:3F:3E:4B:65:2E:7D:46:3F:54:42:CD:54:F1:7A:03:A2:7D:F9:B0:7F:46:19:B2
@ -248,7 +270,7 @@ a=setup:role
</section1>
<section1 topic='Acknowledgements' anchor='acks'>
<p>Thanks to Justin Uberti and Lance Stout.</p>
<p>Thanks to Justin Uberti, Peter Saint-Andre and Lance Stout.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
@ -293,6 +315,11 @@ a=setup:role
<xs:enumeration value='passive'/>
<xs:enumeration value='actpass'/>
<xs:enumeration value='holdconn'/>
<xs:annotation>
<xs:documentation>
the 'holdconn' value is not used and included only for completeness.
</xs:documentation>
</xs:annotation>
</xs:restriction>
</xs:simpleType>
</xs:attribute>

View File

@ -10,7 +10,7 @@
<abstract>This specification describes a solution of marking the last received, displayed and acknowledged message in a chat.</abstract>
&LEGALNOTICE;
<number>0333</number>
<status>Deferred</status>
<status>Experimental</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -27,6 +27,12 @@
<email>im@spencermacdonald.com</email>
<jid>im@spencermacdonald.com</jid>
</author>
<revision>
<version>0.2.1</version>
<date>2015-10-28</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Fixing typo ("cannot" repeated twice) (JC Brand).</p></remark>
</revision>
<revision>
<version>0.2</version>
<date>2013-09-05</date>
@ -133,7 +139,7 @@
<section1 topic='When to send Chat Markers and markable messages' anchor='when'>
<section2 topic='Bare JID' anchor='when-bare'>
<p>If the sender knows only the recipient's bare JID, it cannot cannot determine (via &xep0030; or &xep0115;) whether the intended recipient supports the Chat Markers protocol. In this case, the sender MAY send a Chat Marker or markable message.</p>
<p>If the sender knows only the recipient's bare JID, it cannot determine (via &xep0030; or &xep0115;) whether the intended recipient supports the Chat Markers protocol. In this case, the sender MAY send a Chat Marker or markable message.</p>
</section2>
<section2 topic='Full JID' anchor='when-full'>
<p>If the sender knows a full JID for the recipient (e.g., via presence), it SHOULD attempt to determine (via service disco or entity capabilities) whether the client at that full JID supports the Chat Markers protocol before attempting to send a Chat Marker or markable message.</p>

View File

@ -21,6 +21,15 @@
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
&mwild;
<revision>
<version>0.2</version>
<date>2015-09-01</date>
<initials>dg</initials>
<remark>
<p>Fixed the wrong use of no-storage instead of no-store</p>
<p>Added a message hint &lt;store/&gt;</p>
</remark>
</revision>
<revision>
<version>0.1</version>
<date>2013-07-11</date>
@ -45,6 +54,7 @@
<ul>
<li>Whether to store a message (e.g. for archival or as an 'offline message').</li>
<li>Whether to copy a message to other resources.</li>
<li>Whether to store a message that would not have been stored under normal conditions</li>
</ul>
</section1>
<section1 topic='Use Cases' anchor='usecases'>
@ -74,16 +84,19 @@
recipient is offline at the time of sending). Such a message can be marked with the &lt;no-permanent-store/&gt; hint.
</p>
</section2>
<section2 topic="Storage-worthy messages" anchor='store-worthy'>
<p>Offline storage and &xep0313; can define their own rules on what messages to store and usually only store messages that contain a body element. However a sender may want to indicate that a message is worth storeing even though it might not match those rules (e.g. an encrypted message that carries the payload outside the body element). Such a message can be marked with a &lt;store/&gt; hint.</p>
</section2>
</section1>
<section1 topic="Hints" anchor="hints">
<section2 topic="No permanent storage" anchor="no-permanent-store">
<p>The &lt;no-permanent-storage/&gt; hint informs entities that they shouldn't store the message in
<section2 topic="No permanent store" anchor="no-permanent-store">
<p>The &lt;no-permanent-store/&gt; hint informs entities that they shouldn't store the message in
any permanent or semi-permanent public or private archive (such as described in &xep0136; and &xep0313;)
or in logs (such as chatroom logs).
</p>
</section2>
<section2 topic="No storage" anchor="no-store">
<p>A message containing a &lt;no-storage/&gt; hint should not be stored by a server either permanently (as above)
<section2 topic="No store" anchor="no-store">
<p>A message containing a &lt;no-store/&gt; hint should not be stored by a server either permanently (as above)
or temporarily, e.g. for later delivery to an offline client, or to users not currently present in a chatroom.
</p>
</section2>
@ -95,6 +108,9 @@
occupants in a &xep0045; room.
</p>
</section2>
<section2 topic="Store">
<p>A message containing the &lt;store/&gt; hint that is not of type 'error' SHOULD be stored by the entity.</p>
</section2>
</section1>
<section1 topic='Business Rules' anchor='rules'>
<p>It is important to note that message hints are, as the name implies, just hints. Implementations
@ -122,6 +138,7 @@
<xs:element name='no-permanent-store' type='empty'/>
<xs:element name='no-store' type='empty'/>
<xs:element name='no-copy' type='empty'/>
<xs:element name='store' type='empty'/>
<xs:simpleType name='empty'>
<xs:restriction base='xs:string'>

View File

@ -10,7 +10,8 @@
<abstract>This document defines a way for the client to indicate its active/inactive state.</abstract>
&LEGALNOTICE;
<number>0352</number>
<status>Experimental</status>
<status>Proposed</status>
<lastcall>2015-09-07</lastcall>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -21,6 +22,12 @@
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
&mwild;
<revision>
<version>0.2</version>
<date>2015-10-02</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Clarified how CSI is affected by in-order processing (Florian Schmaus).</p></remark>
</revision>
<revision>
<version>0.1</version>
<date>2014-08-28</date>
@ -55,10 +62,10 @@
<p>Juliet has an XMPP client on her phone, which is available to receive messages. However most of the time
Juliet has her phone screen turned off and is not interested in the status of her contacts unless they are
communicating with her.</p>
<p>Juliet's client informs the server when Juliet is not interacting with it. The server uses this information to
suppress or reduce stanzas that are unimportant, such as status updates.</p>
<p>When Juliet returns to her IM client, the client again informs the server, this time to report that it is active
again. The server then disables its traffic optimisations and restores the stream to its normal state.</p>
</section2>
@ -96,12 +103,12 @@
<example caption='Client indicates it is inactive'><![CDATA[
<inactive xmlns='urn:xmpp:csi:0'/>
]]></example>
<p>As might be anticipated, when the client is active again it sends an &lt;active/&gt; element:</p>
<example caption='Client indicates it is active'><![CDATA[
<active xmlns='urn:xmpp:csi:0'/>
]]></example>
<p>There is no reply from the server to either of these elements (though they may indirectly cause the server to
send stanzas, e.g., to update presence information when the client becomes active after a period of inactivity).</p>
</section2>
@ -109,13 +116,35 @@
<section1 topic='Business Rules' anchor='rules'>
<p>As this protocol is for indication only, clients MUST NOT make assumptions about how the server
will use the active/inactive state information.</p>
<p>The server MUST assume all clients to be in the 'active' state until the client indicates otherwise. Also the
CSI active/inactive state is unrelated to the user's presence, the server MUST treat the two independently.</p>
<p>This protocol is intended primarily for clients with human interaction. Due to the open-ended nature of
the possible optimisations implemented by the server, it may not be suitable for non-IM purposes where the
fully standard behaviour of XMPP is required.</p>
<section2 topic="In-order processing" anchor="in-order-processing">
<p>
XMPP requires stanzas to be processed in order as per &rfc6120; 10.1. Especially "If the server's processing of a particular request could have an effect on its processing of subsequent data it might receive over that input stream..., it MUST suspend processing of subsequent data until it has processed the request.". As a result, all actions triggered by a CSI nonza sent to the server must happen before processing further requests from the same client to the server.
</p>
<p>
For example: A client sends a CSI active nonza, followed by an XMPP Ping request to the server. The server first changes the CSI state to active and flushes all eventually queued stanzsa. After the state has been restored to 'active' and
all resulting stanzas have been put on the wire, the
server sends the pong.
</p>
<example caption='In-order processing'><![CDATA[
<!-- Client sends 'active' and a ping to the server -->
<active xmlns='urn:xmpp:csi:0'/>
<iq to='capulaet.lit' from='juliet@capulet.lit/balcony' id='ping1' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
<!-- Server restores stream state to active,
e.g. by flushing out queued stanzas to the client.
and responds to the ping with a pong -->
<iq to='juliet@capulet.lit/baclony' from='capulet.lit' id='ping1' type='result'/>
<!-- Stream state is now 'active' -->]]></example>
</section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>To protect the privacy of users, servers MUST NOT reveal the clients active/inactive state to other

View File

@ -28,7 +28,14 @@
<email>goffi@goffi.org</email>
<jid>goffi@jabber.fr</jid>
</author>
<revision>
<version>0.2.1</version>
<date>2015-10-15</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Corrected examples (Stefan Strigler).</p></remark>
</revision>
<revision>
<version>0.2</version>
<date>2014-03-21</date>
@ -48,14 +55,14 @@
</ul>
</remark>
</revision>
<revision>
<version>0.1</version>
<date>2014-12-18</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
</revision>
<revision>
<version>0.0.1</version>
<date>2014-11-13</date>
@ -95,7 +102,7 @@
<section1 topic='Admin Mode Use Cases' anchor='admin_usecases'>
<section2 topic='Server Allows Namespaces Delegations' anchor='server_config'>
<p>Namespaces delegations are granted in the server configuration. Only &IQ; stanza namespaces can be delegated.</p>
<p>Namespaces delegations are granted in the server configuration. Only &IQ; stanza namespaces can be delegated.</p>
<p>A feature is delegated using:</p>
<ol>
<li>it's namespace: e.g. <em>'urn:xmpp:mam:0'</em></li>
@ -107,11 +114,11 @@
<section2 topic='Delegation Request Use Case' anchor='admin_perm'>
<p>Once the managing entity is authenticated and stream is started, the server send it a &MESSAGE; stanza with a &lt;delegation/&gt; elements which MUST have the <strong>'urn:xmpp:delegation:1'</strong> namespace. This element contains &lt;delegated/&gt; elements which MUST contain a 'namespace' attribute indicating the delegated namespace. If there is additional attribute filtering, the &lt;delegated/&gt; can have children &lt;attribute/&gt; elements which MUST contain a 'name' attribute with the name of the filtering attribute.</p>
<example caption='server advertise delegated namespaces'><![CDATA[
<message from='capulet.net' to='pubub.capulet.lit' id='12345'>
<message from='capulet.lit' to='pubub.capulet.lit' id='12345'>
<delegation xmlns='urn:xmpp:delegation:1'>
<delegated namespace='urn:xmpp:mam:0'>
<attribute name='node' />
<delegated/>
</delegated>
<delegated namespace='http://jabber.org/protocol/pubsub'/>
</delegation>
</message>
@ -166,7 +173,7 @@
</iq>
]]></example>
<p>The managing entity replies to the stanza by encapsulating its &IQ; result in the same way:</p>
<example caption='pubsub.capulet.lit replies badly to juliet'><![CDATA[
<example caption='pubsub.capulet.lit replies to juliet'><![CDATA[
<iq from='pubsub.capulet.lit'
to='capulet.lit'
id='delegate1'
@ -292,7 +299,7 @@
<p>In <em>client</em> mode, the managing entity is not certified by the server administrator, so the delegation MUST be <strong>explicitly</strong> allowed by the managed entity. This is initiated by the managing entity (it can be after an interaction with a managed entity, like a subscription).</p>
<p>To request delegation for a particular entity, the managing entity MUST have an &IQ; stanza with <em>'urn:xmpp:delegation:1'</em> namespace. The &QUERY; element MUST have a 'to' attribute which specify the entity it wants to manage.</p>
<p>Namespace delegations are asked with a &lt;delegate/&gt; element, which MUST contain a 'namespace' attribute set to the requested namespace.</p>
<p>If an entity want to manage PEP service for Juliet, it can ask the delegation like this:
</p>
<example caption='managing entity asks for namespace delegation for one particular entity'><![CDATA[

View File

@ -6,7 +6,7 @@
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Push</title>
<title>Push Notifications</title>
<abstract>This specification defines a way for an XMPP servers to deliver information for use in push notifications to mobile and other devices.</abstract>
&LEGALNOTICE;
<number>0357</number>
@ -29,6 +29,12 @@
<email>lancestout@gmail.com</email>
<jid>lance@lance.im</jid>
</author>
<revision>
<version>0.2</version>
<date>2015-09-10</date>
<initials>lance</initials>
<remark><p>Change the name to 'Push Notifications' based on feedback.</p></remark>
</revision>
<revision>
<version>0.1</version>
<date>2015-03-18</date>
@ -52,7 +58,7 @@
<p>The purpose of push notifications is to inform users of new messages or other pertinent information even when they have no XMPP clients online.</p>
<p>Typically, these notifications are delivered to a user's mobile device, displaying a notice that can trigger opening an XMPP client to continue a conversation or answer a Jingle session request.</p>
<p>There have been several push noticiations implementations by mobile XMPP client vendors. However, experience has shown that these implementations carried several drawbacks:</p>
<p>There have been several push notification implementations by mobile XMPP client vendors. However, experience has shown that these implementations carried several drawbacks:</p>
<ul>
<li>Treated the XMPP client and XMPP server as one unified service, such that push notifications only worked using the "official" client.</li>
<li>Proxied a user's session through the client provider's backend services in order to monitor for and trigger push notifications.</li>
@ -76,7 +82,7 @@
<li>The third-party (and potentially proprietary or platform-dependent) push service delivers the notification from the client application's backend service to the user's device.</li>
</ol>
<p>This two-tiered push architecture allows the user's XMPP server to deliver notifications to arbitrary third-pary clients, and in turn allows those clients to use the appropriate delivery mechanism for their platforms without having to share any private keys or other credentials with the XMPP server.</p>
<p>This two-tiered push architecture allows the user's XMPP server to deliver notifications to arbitrary third-party clients, and in turn allows those clients to use the appropriate delivery mechanism for their platforms without having to share any private keys or other credentials with the XMPP server.</p>
<section2 topic='General Architecture of a Push Notification Service' anchor='general-architecture'>
<p>The current state-of-the-art for a generic push notification service requires four actors:</p>
@ -335,7 +341,7 @@
<p>If additional data was provided when enabling the service, the publish request SHOULD include the data as publish options.</p>
<example caption='Server publishes a push notifictation with provided publish options'><![CDATA[
<example caption='Server publishes a push notification with provided publish options'><![CDATA[
<iq type='set'
from='user@example.com'
to='push-5.client.example'

View File

@ -25,6 +25,12 @@
&fippo;
&lance;
&stpeter;
<revision>
<version>0.2</version>
<date>2015-08-11</date>
<initials>ls</initials>
<remark><p>Add &lt;uri/&gt; element.</p></remark>
</revision>
<revision>
<version>0.1</version>
<date>2015-06-29</date>
@ -63,6 +69,7 @@
<jinglepub xmlns='urn:xmpp:jinglepub:1'
from='sender-jid'
id='someid'>
[<uri/> element for an alternate or informational URI of the content]
[<meta/> element(s) for human-friendly information]
[<description/> element(s) for application format(s)]
</jinglepub>
@ -71,6 +78,7 @@
<p>The 'id' attribute is an opaque identifier. This attribute MUST be present, and MUST be a valid non-empty string. It uniquely identifies the published request at the session owner's JID.</p>
<p>The &lt;jinglepub/&gt; element MUST contain a &lt;description/&gt; element qualified by the namespace of the relevant Jingle application format (e.g., &lt;description xmlns='urn:xmpp:jingle:apps:file-transfer:4'/&gt; for file transfer).</p>
<p>The &lt;jinglepub/&gt; element MAY contain one or more &lt;meta/&gt; elements qualified by the jingle-pub namespace; if more than one element is included, each element MUST have a different value for the 'xml:lang' attribute.</p>
<p>The &lt;jinglepub/&gt; element MAY contain a &lt;uri/&gt; element which contains a URI for an alternative way to access the content, or other information about the content. The resource provided by the URI SHOULD be meaningful for clients that do not directly support the included Jingle content definitions, and accessing the URI MAY result in a different experience than initiating the published Jingle session. For example, the URI could be to a content landing page of an image hosting service from which an image could be viewed instead of directly downloading the image file.</p>
<p>The &lt;jinglepub/&gt; information is typically provided via pubsub.</p>
<p>The following example shows a possible payload for streaming of recorded audio/video sessions, here pushed out via PEP.</p>
<example caption='Sender advertises session via PEP'><![CDATA[
@ -251,10 +259,11 @@
<xs:element name='jinglepub'>
<xs:complexType>
<xs:sequence>
<xs:any namespace='##other' minOccurs='1' maxOccurs='unbounded'/>
<xs:element name='meta' type='metaElementType'/>
</xs:sequence>
<xs:all>
<xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
<xs:element name='meta' type='metaElementType' minOccurs='0' maxOccurs='unbounded' />
<xs:element name='uri' type='xs:anyURI' minOccurs='0' maxOccurs='1' />
</xs:all>
<xs:attribute name='description' type='xs:string' use='optional'/>
<xs:attribute name='from' type='xs:string' use='required'/>
<xs:attribute name='id' type='xs:string' use='required'/>

View File

@ -19,13 +19,33 @@
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED (suggested: sid)</shortname>
<shortname>stanza-id</shortname>
<author>
<firstname>Florian</firstname>
<surname>Schmaus</surname>
<email>flo@geekplace.eu</email>
<jid>flo@geekplace.eu</jid>
</author>
<revision>
<version>0.2.1</version>
<date>2015-09-22</date>
<initials>fs</initials>
<remark>
<p>Minor fixes (typos, s/JID/XMPP Address, etc.)</p>
</remark>
</revision>
<revision>
<version>0.2</version>
<date>2015-09-18</date>
<initials>fs</initials>
<remark>
<ul>
<li>Refactored client-id from attribute to element.</li>
<li>Set short name to 'stanza-id'.</li>
<li>Clarified that SID elements must not have additional content.</li>
</ul>
</remark>
</revision>
<revision>
<version>0.1</version>
<date>2015-07-14</date>
@ -63,21 +83,21 @@
id='de305d54-75b4-431b-adb2-eb6b9e546013'
by='room@muc.xmpp.org'/>
]]></example>
In order to create a 'stanza-id' extension, the creating XMPP entity generates and sets the value of the 'id' attribute, and puts its own JID as value of the 'by' attribute. The value of the 'id' attribute must be unique and stable, i.e. it MUST NOT change later for some reason, within the scope of the 'by' value. Thus the IDs defined in this extension MUST be unique and stable within the scope of the generating XMPP entity. It is RECOMMENDED that the ID generating service uses UUID and the algorithm defined in RFC 4122, to generate the IDs.
In order to create a 'stanza-id' extension, the creating XMPP entity generates and sets the value of the 'id' attribute, and puts its own XMPP address as value of the 'by' attribute. The value of the 'id' attribute must be unique and stable, i.e. it MUST NOT change later for some reason, within the scope of the 'by' value. Thus the IDs defined in this extension MUST be unique and stable within the scope of the generating XMPP entity. It is RECOMMENDED that the ID generating service uses UUID and the algorithm defined in RFC 4122 to generate the IDs.
</section2>
<section2 topic='Client generated stanza IDs' anchor='client-id'>
<p>
Some use cases require the client to generate the stanza ID. In this case, the client MUST use 'client-id' as attribute name for the ID.
Some use cases require the client to generate the stanza ID. In this case, the client MUST use the 'client-id' element.
</p>
<example caption='A message stanza with the stanza ID extension.'><![CDATA[
<message xmlns='jabber:client'
to='room@muc.example.org'
type='groupchat'>
<body>Typical body text</body>
<stanza-id xmlns='urn:xmpp:sid:0' client-id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
<client-id xmlns='urn:xmpp:sid:0' id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
</message>]]></example>
<p>
The server MAY add an 'id' attribute to the stanza-id element. In that case, it MUST preserve the content of the 'client-id' attribute.
The server or component MAY add a stanza-id element. In that case, it MUST preserve the content of the 'client-id' element.
</p>
<example caption='A message stanza with the stanza ID extension.'><![CDATA[
<message xmlns='jabber:client'
@ -85,28 +105,25 @@
type='groupchat'>
<body>Typical body text</body>
<stanza-id xmlns='urn:xmpp:sid:0'
id='new-id-overrides-client-id'
by='room@muc.example.org'
client-id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
id='5f3dbc5e-e1d3-4077-a492-693f3769c7ad'
by='room@muc.example.org'/>
<client-id xmlns='urn:xmpp:sid:0' id='de305d54-75b4-431b-adb2-eb6b9e546013'/>
</message>]]></example>
<p>
Otherwise, if the server does not override the ID, it MAY omit the 'client-id' attribute.
</p>
</section2>
</section1>
<section1 topic='Business Rules' anchor='rules'>
<ol>
<li>XMPP entities, which are routing stanzas, MUST NOT strip stanza-id elements from message stanzas.</li>
<li>The values of the 'id' (and 'client-id') attribute SHOULD be unpredictable.</li>
<li>Stanza ID generating entities, which encounter a &lt;stanza-id/&gt; element where 'id' (and 'client-id') is already set and where the 'by' attribute matches their own JID, MUST ignore the existing value of 'id' and override it.</li>
<li>Stanzas MUST posses, in the direct child level of the stanza, at most one 'stanza-id' extension element with the same JID as value of the 'by' attribute.</li>
<li>Stanza ID extension elements which have a 'id' attribute MUST also have the 'by' attribute set.</li>
<li>Stanza ID extension elements MUST either posses a 'id' attribute, a 'client-id' attribute or both.</li>
<li>The value of the 'by' attribute MUST be a normalized JID as defined in &rfc6122;</li>
<li>XMPP entities, which are routing stanzas, MUST NOT strip any elements qualified by the 'urn:xmpp:sid:0' namespace from message stanzas. They SHOULD however ensure that those elements contain only the attributes defined herein, and take appropriate countermeasures if this is not the case (e.g. removing those attributes).</li>
<li>The values of the 'id' attribute SHOULD be unpredictable.</li>
<li>Stanza ID generating entities, which encounter a &lt;stanza-id/&gt; element where 'id' is already set and where the 'by' attribute matches their own XMPP address, MUST ignore the existing value of 'id' and override it.</li>
<li>Stanzas MUST posses, in the direct child level of the stanza, at most one 'stanza-id' extension element with the same XMPP address as value of the 'by' attribute.</li>
<li>Every &lt;stanza-id&gt; extension element MUST have the 'id' attribute and the 'by' attribute set.</li>
<li>Every &lt;stanza-id&gt; and &lt;client-id&gt; extension element MUST always posses an 'id' attribute and MUST NOT have any child elements or text content.</li>
<li>The value of the 'by' attribute MUST be the XMPP address of the entity assigning the unique and stable stanza ID. Note that XMPP addresses are normalized as defined in &rfc6122;</li>
</ol>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>The value of the 'id' attribute should not provide any further information besides the opaque ID itself. Entities observing the value MUST NOT be able to infer any information from it, e.g. the size of the message archive. The value of 'id' and 'client-id' MUST be considered as non-secret values.</p>
<p>The value of the 'id' attribute should not provide any further information besides the opaque ID itself. Entities observing the value MUST NOT be able to infer any information from it, e.g. the size of the message archive. The value of 'id' MUST be considered a non-secret value.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with &IANA;.</p>

202
xep-0362.xml Normal file
View File

@ -0,0 +1,202 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Raft over XMPP</title>
<abstract>This specification provides a means for transporting messages from the Raft consensus algorithm over XMPP.</abstract>
&LEGALNOTICE;
<number>0362</number>
<status>Experimental</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>XEP-0001</spec>
<spec>Etc.</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
<author>
<firstname>Peter</firstname>
<surname>Membrey</surname>
<email>peter@membrey.hk</email>
<jid>peter@membrey.hk</jid>
</author>
<revision>
<version>0.1</version>
<date>2015-08-11</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
</revision>
<revision>
<version>0.0.3</version>
<date>2015-07-28</date>
<initials>pm</initials>
<remark><p>Removed references to SHOULD/MUST.</p></remark>
</revision>
<revision>
<version>0.0.2</version>
<date>2015-07-22</date>
<initials>pm</initials>
<remark><p>Updates based on list and council feedback.</p></remark>
</revision>
<revision>
<version>0.0.1</version>
<date>2015-07-20</date>
<initials>pm</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>This XEP does not attempt to implement Raft. Rather, based on the message exchanges defined in the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link>, it defines a complementary set of &MESSAGE; stanza elements to allow Raft messages to be transported cleanly over XMPP. The messages for Node to Node communication are well documented in the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link> and are reproduced here with minor additions to leverage the benefits of XMPP. However Client to Node communication is only hinted at and, as it does not use Raft natively it is outside the scope of this XEP.</p>
<p>Raft is a consensus algorithm that is easy to understand and implement. When you want to keep a distributed system consistent, you will need some form of consensus algorithm. Raft was developed at Stanford University as an alternative to the incumbent consensus algorithm PAXOS. PAXOS is claimed to be very complex, hard to teach and even harder to implement. All of these are discussed in a paper <link url="https://ramcloud.stanford.edu/raft.pdf">here</link> and additional information (including a graphical simulation of a cluster) can be found on the project's website: <link url="https://raftconsensus.github.io/">https://raftconsensus.github.io/</link>.</p>
<p>Raft defines a set of core messages needed to implement the protocol. However, it does not specify the transport layer for this protocol. Most implementations have chosen to use vanilla TCP due to its simplicity. However if you want to run a cluster over the Internet, you are likely going to want more than what vanilla TCP provides. This is where XMPP would really shine as a transport layer for Raft. XMPP offers:</p>
<ol>
<li> Encrypted transport (TLS) </li>
<li> Authenticated Endpoints </li>
<li> Ability to use JIDs to identify cluster nodes </li>
<li> Re-use XMPP if the application is already XMPP enabled </li>
</ol>
<p>These are all things that would traditionally have to be re-engineered each time somebody wanted to use Raft across the public Internet. By supporting Raft in XMPP, developers looking to use Raft would have a transport layer that's as easy to use and understand as the Raft protocol itself. As Raft does not offer its own transport protocol and has deliberately left that to the developer, there is no conflict in standardizing an XMPP based transport layer.</p>
<section2 topic='Why &MESSAGE; and not &IQ;'>
<p>The Raft algorithm can be categorized as a request-response protocol. Normally this would make it a prime candidate for using &IQ; stanzas to handle the communication. However because Raft is designed to cope with message loss, it intrinsically supports automatic recovery. There is no need for the transport layer to report errors as even if the transport layer provided them (such as an &IQ; 'error' response), the Raft implementation cannot use it.</p>
<p>This has a number of benefits. First, it makes Raft adaptable to lossy transport layers where packets can (and do) get lost. Raft is able to automatically recover in this scenario because the next message the Leader sends will allow a Follower to detect that it has missed a message and ask for it to be sent again. The Leader has no way to deal with an error condition caused by sending a message to a Follower.</p>
<p>Second, when it comes to implementing Raft over XMPP, using &MESSAGE; instead of &IQ; greatly simplifies the implementation. As &IQ; stanzas require a reply, the implementation would need to handle detecting and reporting errors conditions back to the sender. This could mean adding arbitrary timers to try to determine if a Follower has 'timed out'. This adds complexity and uncertainty to the system, and given that Raft itself cannot make use of this information, using &IQ; does not add any value to the Raft over XMPP protocol.</p>
</section2>
<section2 topic='Example Usecase'>
<p>Making databases or datastores available over the Internet has been the norm for many years. Databases containing PGP keys, certificates or other information can be found hosted by many different organizations. The problem with these systems is that as they become more critical to users, the impact of a server failing increases dramatically. For example, a server that provides a spam database that clients can verify email against, must be operational for those clients to be able to filter spam. Having a single server in this scenario is not acceptable; to provide redundancy there must be multiple servers.</p>
<p>The problem then becomes how to keep the servers in sync. Raft partly solves this problem by providing the means to ensure the cluster maintains consensus i.e. maintains a consistent view of the data. As mentioned previously, it does not however provide a means for the nodes in the cluster to actually communicate with each other or clients.</p>
<p>This is where being able to use Raft over XMPP would be highly beneficial. As it stands now, developers must implement their own transport and security, which although certainly possible, is not ideal. First, most developers are not security experts and a wealth of knowledge and experience is needed to properly design a secure system. Second, even with the required expertise, it takes a considerable amount of time and effort to actually implement and test any new implementation. Third, this extra work takes developers' focus away from the problem that they were trying to solve in the first place.</p>
<p>So how could Raft over XMPP be applied in this instance? First, XMPP has an excellent history when it comes to security. Considerable time and effort was spent ensuring that XMPP was secure when XMPP Core was being standardized. By using XMPP, this hard work and battle tested approach can be leveraged by Raft. This means developers do not need to concern themselves with securing Raft messages, rather they now only need to concern themselves with using XMPP appropriately.</p>
<p>Raft over XMPP further simplifies things by allowing developers to think at a higher level of abstraction. Nodes in the cluster can be communicated with simply by knowing their JID. It would not be necessary to know a node's IP address (which could change) or what TCP port the node is running on. In addition developers would not need to worry about which node connects to which, managing multiple TCP sockets and how to multiplex data across them.</p>
<p>Lastly, integrating a Raft implementation with Raft over XMPP, would be relatively straight forward as Raft over XMPP defines and uses the same names as those provided by the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link> with few additions. This means that it could be much easier to get a Raft implementation up and running using Raft over XMPP than it would be to do so even with pure vanilla sockets.</p>
</section2>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<p>The author has designed Raft over XMPP with the following requirements in mind:</p>
<ol>
<li> The protocol needs to support all messages as defined in the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link> </li>
<li> The protocol ought to leverage the benefits of using XMPP as the transport layer </li>
<li> Client to Node interaction is out of scope for this XEP</li>
</ol>
</section1>
<section1 topic='Glossary' anchor='glossary'>
<dl>
<di><dt>Raft</dt><dd>A distributed consensus algorithm designed at Stanford University to be simple and easy to implement. It aims to replace PAXOS as the conensus algorithm of choice for real world use and teaching. The Raft website is <link url="https://raftconsensus.github.io/">https://raftconsensus.github.io/</link></dd></di>
<di><dt>Log Replication</dt><dd>Log replication is how Raft exchanges commands with the rest of the cluster.</dd></di>
<di><dt>Follower</dt><dd>The default state of a cluster member. It receives and applies updates from the Leader</dd></di>
<di><dt>Candidate</dt><dd>When a Follower has not seen a heartbeat from the Leader for a period of time, it will assume the leader has failed and will look to become the Leader itself.</dd></di>
<di><dt>Leader</dt><dd>The Leader of the cluster is responsible for making all changes to the log and sending them to the other members of the cluster</dd></di>
<di><dt>VoteRequest</dt><dd>A VoteRequest message is sent by a Candidate in order to solicit votes to become the Leader of a cluster</dd></di>
<di><dt>AppendEntries</dt><dd>An AppendEntries message is sent by a Leader to other nodes in the cluster when it has updates that it needs to replicate.</dd></di>
</dl>
</section1>
<section1 topic='Protocol' anchor='protocol'>
<p>This XEP defines a transport layer for Raft and not an actual implementation. That is, it does not seek to implement the Raft consensus algorithm within XMPP, but instead to simply define the means for Raft messages to be transported over XMPP. To facilitate this, both the message name used in the Raft spec (shown in camel case) and the corresponding element name are mentioned together where appropriate.</p>
<p>Node to Node communication is the back-bone of a Raft cluster. In operation, only the Leader or a Candidate will send messages. In all other cases, nodes will only reply to messages received. The two messages are AppendEntries and RequestVote.</p>
<section2 topic="RequestVote">
<p>When a Follower has not received a heartbeat from the Leader for a given period of time, it will determine that the Leader has failed and will seek to replace it. To do this it needs the support of the majority of nodes in the cluster. It can solicit support from other nodes by declaring itself a Candidate and sending a 'request-vote' (RequestVote) message to all nodes in the cluster:</p>
<example caption="Duncan is soliciting votes to become leader of the cluster"><![CDATA[
<message from="duncan@inverness.lit/castle" to="macbeth@cawdor.lit/castle">
<request-vote xmlns="urn:xmpp:raft" term="1" last-log-term="1" last-log-index="1" cluster="scotland"/>
</message>
]]></example>
<p>A node will respond with a 'vote' (RequestVoteResponse) message:</p>
<example caption="Macbeth votes for Duncan to become the next leader"><![CDATA[
<message from="macbeth@cawdor.lit/castle" to="duncan@inverness.lit/castle">
<vote xmlns="urn:xmpp:raft" term="1" vote-granted="true" cluster="scotland"/>
</message>
]]></example>
<p> A node can either vote for a given Candidate (vote-granted="true") or against a Candidate (vote-granted="false").</p>
<p>If a node does not receive a reply, no special handling is required.</p>
</section2>
<section2 topic="AppendEntries">
<p>The 'append' (AppendEntries) message is used by the Leader to tell Followers that they should append a new entry (or entries) to their logs. It contains additional information to allow a Follower to determine which log entries have been executed and committed on the Leader and also if it has dropped any messages. These features are implemented in Raft directly.</p>
<example caption="Duncan sends an append message to his followers"><![CDATA[
<message from="duncan@inverness.lit/castle" to="macbeth@cawdor.lit/castle">
<append xmlns="urn:xmpp:raft" term="1" prev-log-index="1" leader-commit="1" cluster="scotland">
<entry xmlns="urn:xmpp:raft" encoded="false">
SET X = 1
</entry>
<entry xmlns="urn:xmpp:raft" encoded="true">
U0VUIFggPSAx
</entry>
</append>
</message>
]]></example>
<p>The AppendEntries message is described as a simple array in the <link url="https://ramcloud.stanford.edu/raft.pdf">Raft paper</link> and this has been expanded on in XMPP to take advantage of structured XML. In addition, Raft is designed to be able to replicate any form of command and this could be binary data rather than textual data. To accommodate this, an attribute has been added to the 'append-entries' element to allow a sender to flag when the receiver needs to decode the Entry before passing it to the Raft implementation. The data is encoded using base64.</p>
<p>When followers receive this message, they send a single 'append-response' (AppendEntriesResponse) in reply as follows:</p>
<example caption="Macbeth sends an append-response message to Duncan"><![CDATA[
<message from="macbeth@cawdor.lit/castle" to="duncan@inverness.lit/castle">
<append-response xmlns="urn:xmpp:raft" term="1" success="true" cluster="scotland"/>
</message>
]]></example>
<p>As before, if a message is missed in either direction, the transport layer does not need to take action.</p>
</section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<section2 topic='Checking cluster membership'>
<p>It is not the responsibility of the transport layer to determine whether a node is a member of a cluster or not before delivering messages to the Raft implementation. The Raft implementation should ignore messages that it receives from nodes that aren't part of the cluster.</p>
</section2>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with the Internet Assigned Numbers Authority (IANA).</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>The &REGISTRAR; includes 'urn:xmpp:raft' in its registry of protocol namespaces.</p>
</section2>
</section1>
<section1 topic='XML Schema' anchor='schema'>
<p>REQUIRED for protocol specifications.</p>
</section1>
</xep>

199
xep-0363.xml Normal file
View File

@ -0,0 +1,199 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>HTTP File Upload</title>
<abstract>This specification defines a protocol to request permissions from another entity to upload a file to a specific path on an HTTP server and at the same time receive a URL from which that file can later be downloaded again.</abstract>
&LEGALNOTICE;
<number>0363</number>
<status>Experimental</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>XEP-0001</spec>
<spec>Etc.</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
<author>
<firstname>Daniel</firstname>
<surname>Gultsch</surname>
<email>daniel@gultsch.de</email>
<jid>daniel@gultsch.de</jid>
</author>
<revision>
<version>0.1</version>
<date>2015-08-27</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
</revision>
<revision>
<version>0.0.1</version>
<date>2015-07-25</date>
<initials>dg</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>XMPP protocol extensions already define methods for peer-to-peer file transfer such as &xep0096; or &xep0234; however due to their very nature of being peer-to-peer they don't work very well in scenarios where it is requeried to send a file to multiple receipients or multiple resources of the same receipient at once. They also dont work alongside offline storage, MUC history and &xep0313;.</p>
<p>Uploading files manually to an HTTP server and sharing the link has been a workaround for this for a long time now. While users have a variety of services to choose from the downside of this manual approach is that an XMPP client can not automate this process on behalf of the user since these services dont share a common api. Furthermore using a third party service would probably require the user to enter addional credentials into their XMPP client specifically for the file upload.</p>
<p>This XEP defines an approach to request permissions from another entity to upload a file to a specific path on an HTTP server and at the same time receive an URL from which that file can later be downloaded again. These tuples consisting of a PUT and a GET-URL are called slots.</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<ul>
<li>Be as easy to implement as possible. This is grounded on the idea that most programming languages already have HTTP libraries available.</li>
<li>Be agnostic toward the distributon of the actual URL. Users can choose to send the URL in the body of a message stanza, utilize &xep0066; or even use it as their avatar in &xep0084;</li>
<li>Do not provide any kind of access control or security beyond Transport Layer Security in form of HTTPS and long random pathes that are impossible to guess. That means everyone who knows the URL SHOULD be able to access it.</li>
</ul>
</section1>
<section1 topic='Discovering Support' anchor='disco'>
<p>An entity advertises support for this protocol by including the "urn:xmpp:http:upload" in its service discovery information features as specified in &xep0030; or section 6.3 of &xep0115;. A users server SHOULD include any known entities that provide such services into its service discovery items.</p>
<example caption='Client sends service discovery request to server'><![CDATA[
<iq from='romeo@montague.tld/garden'
id='step_01'
to='montague.tld'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>]]></example>
<example caption='Server replies to service discovery request'><![CDATA[
<iq from='montague.tld'
id='step_01'
to='romeo@montague.tld/garden'
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='upload.montague.tld' name='HTTP File Upload' />
<item jid='conference.montague.tld' name='Chatroom Service' />
</query>
</iq>]]></example>
<example caption='Client sends service discorvey request to upload service'><![CDATA[
<iq from='romeo@montague.tld/garden
id='step_02'
to='upload.montague.tld'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>]]></example>
<example caption='Upload service replies to service discovery request'><![CDATA[
<iq from='upload.montague.tld
id='step_02'
to='romeo@montague.tld/garden'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity category='store'
type='file'
name='HTTP File Upload' />
<feature var='urn:xmpp:http:upload' />
</query>
</iq>]]></example>
</section1>
<section1 topic='Requesting a slot' anchor='request'>
<p>A client requests a new upload slot by sending an IQ-get to the upload service containing a &lt;request&gt; child element qualified by the urn:xmpp:http:upload namespace. This element MUST include elements &lt;filename&gt; and &lt;size&gt; containing the file name and size respectively.</p>
<p>An additional element &lt;content-type&gt; containing the Content-Type is OPTIONAL.</p>
<example caption='Client requests a slot on the upload service'><![CDATA[
<iq from='romeo@montague.tld/garden
id='step_03'
to='upload.montague.tld'
type='get'>
<request 'urn:xmpp:http:upload'>
<filename>my_juliet.png</filename>
<size>23456</size>
<content-type>image/jpeg</content-type>
</request>
</iq>]]></example>
<p>The upload service responds with both a PUT and a GET URL wrapped by a &lt;slot&gt; element. The service SHOULD keep the file name and especially the file ending intact. Using the same hostname for PUT and GET is OPTIONAL. The host SHOULD provide Transport Layer Security.</p>
<example caption='The upload service responsd with a slot'><![CDATA[
<iq from='upload.montague.tld
id='step_03'
to='romeo@montague.tld/garden
type='result'>
<slot xmlns='urn:xmpp:http:upload'>
<put>https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png</put>
<get>https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png</get>
</slot>
</iq>]]></example>
</section1>
<section1 topic='Error conditions' anchor='errors'>
<p>Instead of providing the client with a slot the service MAY respond with an error if the requested file size is too large.</p>
<example caption='Alternative response by the upload service if the file size was too large'><![CDATA[
<iq from='upload.montague.tld
id='step_03'
to='romeo@montague.tld/garden
type='error'>
<request 'urn:xmpp:http:upload>
<filename>my_juliet.png</filename>
<size>23456</size>
</request>
<error type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' />
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas>file too large. the maximum file size is 20000 bytes</text>
<file-too-large xmlns='urn:xmpp:http:upload'>
<max-size>20000</max-size>
</file-too-large>
</error>
</iq>]]></example>
<p>For any other type of error the service SHOULD respond with appropriate error types to indicate temporary or permanent errors.</p>
<example caption='Alternative response by the upload service to indicate a temporary error after the client exceeded a quota'><![CDATA[
<iq from='upload.montague.tld
id='step_03'
to='romeo@montague.tld/garden
type='error'>
<request 'urn:xmpp:http:upload>
<filename>my_juliet.png</filename>
<size>23456</size>
</request>
<error type='wait'>
<resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' />
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas>Quota reached. You can only upload 5 files in 5 minutes</text>
</error>
</iq>]]></example>
<example caption='Alternative response by the upload service to indicate a permanent error to a client that is not allowed to upload files'><![CDATA[
<iq from='upload.montague.tld
id='step_03'
to='romeo@montague.tld/garden
type='error'>
<request 'urn:xmpp:http:upload>
<filename>my_juliet.png</filename>
<size>23456</size>
</request>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' />
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas>Only premium members are allowed to upload files</text>
</error>
</iq>]]></example>
</section1>
<section1 topic='Upload' anchor='upload'>
<p>The actual upload of the file happens via HTTP-PUT and is out of scope of this document. The upload service MUST reject the file upload if the Content-Length does not match the size of the slot request. The service SHOULD reject the file if the Content-Type has been specified beforehand and does not match. The service MAY assume application/octet-stream as a Content-Type if it the client did not specficy a Content-Type at all.</p>
<p>There is no further XMPP communication required between the upload service and the client. A HTTP status Code of 201 means that the server is now ready to serve the file via the provided GET URL. If the upload fails for whatever reasons the client MAY request a new slot.</p>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
<p>The upload service SHOULD choose an appropriate timeout for the validity of the PUT URL. Since there is no reason for a client to wait between requesting the slot and starting the upload relativly low time out values of around 60s are RECOMENDED.</p>
<p>It is RECOMMENDED that the service stores the files for as long as possible which is of course limited by storage capacity. A service MAY choose to store the latest x MiB of a given user.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<ul>
<li>Client implementors MUST consider the fact that without additional end-to-end-encryption files uploaded to a service described in this document will store those files in plain text on that service. Client implementors SHOULD either use this only for semi public files (for example files shared in a public MUC or a PEP Avatar) or implement appropriate end-to-end encryption.</li>
<li>Service implementors SHOULD use long randomized parts in their URLs making it impossible to guess the location of arbitrary files</li>
<li>Server operators SHOULD consider the responsibilty that comes with storing user data and MAY consider appropriate measures such as full disk encryption.</li>
</ul>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with the Internet Assigned Numbers Authority (IANA).</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>This specification defines the following XML namespace:</p>
<ul>
<li>urn:xmpp:http:upload</li>
</ul>
<p>Upon advancement of this specification from a status of Experimental to a status of Draft, the &REGISTRAR; shall add the foregoing namespace to the registry located at &NAMESPACES;, as described in Section 4 of &xep0053;.</p>
</section2>
</section1>
<section1 topic='XML Schema' anchor='schema'>
<p>tbd</p>
</section1>
</xep>

291
xep-0364.xml Normal file
View File

@ -0,0 +1,291 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Current Off-the-Record Messaging Usage</title>
<abstract>
This document outlines the current usage of Off-the-Record messaging in
XMPP, its drawbacks, its strengths, and recommendations for improving the
end user experience.
</abstract>
&LEGALNOTICE;
<number>0364</number>
<status>Experimental</status>
<type>Informational</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>NOT_YET_ASSIGNED</shortname>
<author>
<firstname>Sam</firstname>
<surname>Whited</surname>
<email>sam@samwhited.com</email>
<jid>sam@samwhited.com</jid>
</author>
<revision>
<version>0.1</version>
<date>2015-08-27</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
</revision>
<revision>
<version>0.0.1</version>
<date>2015-07-28</date>
<initials>ssw</initials>
<remark><p>Initial draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>
The Off-the-Record messaging protocol (OTR) was originally introduced in
the 2004 paper
<i><link url='https://otr.cypherpunks.ca/otr-wpes.pdf'>
Off-the-Record Communication, or, Why Not To Use PGP
</link></i>
<note>
Nikita Borisov, Ian Goldberg, Eric Brewer (2004-10-28). "Off-the-Record
Communication, or, Why Not To Use PGP"
&lt;<link url='https://otr.cypherpunks.ca/otr-wpes.pdf'>
https://otr.cypherpunks.ca/otr-wpes.pdf
</link>&gt;
</note>
and has since become the de facto standard for performing end-to-end
encryption in XMPP. OTR provides encryption, deniable authentication,
forward secrecy, and malleable encryption.
</p>
<p>
The OTR protocol itself is currently described by the document:
<i><link url='https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html'>
Off-the-Record Messaging Protocol version 3
</link></i>
<note>
"Off-the-Record Messaging Protocol version 3"
&lt;<link url='https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html'>
https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html
</link>&gt;
</note>
and will not be redescribed here. Instead, this document aims to describe
OTR's usage and best practices within XMPP. It is not intended to be a
current standard, or technical specification, as better (albeit, newer and
less well tested) methods of end-to-end encryption exist for XMPP.
</p>
</section1>
<section1 topic='Overview' anchor='overview'>
<p>
Though this document will not focus on the OTR protocol itself, a brief
overview is warranted to better understand the protocols strengths and
weaknesses.
</p>
<p>
OTR uses 128 bit AES symmetric-key encryption and the SHA-1 hash function.
An OTR session can be held only between two parties, meaning that OTR is
incompatible with &xep0045;. It provides deniability in the form of
malleable encryption (a third party may generate fake messages after the
session has ended). This means that if you were not a part of the original
conversation, you cannot prove based on captured messages alone that a
message from the conversation was actually sent by a given party. Unlike
PGP, OTR also provides forward secrecy; even if a session is recorded and
the primary key is compromised at a later date, the OTR messages will not
be able to be decrypted as each was encrypted with an ephemeral key
exchanged with Diffie-Hellman key exchange with a 1536 bit modulus.
</p>
</section1>
<section1 topic='Discovery'>
<p>
Clients that support the OTR protocol do not advertise it in any of the
normal XMPP ways. Instead, OTR provides its own discovery mechanism. If a
client wishes to indicate support for OTR they include a special whitespace
tag in their messages. This tag can appear anywhere in the body of the
message stanza, but it is most often found at the end. The OTR tag
comprises the following bytes:
<example caption='OTR tag'>
\x20\x09\x20\x20\x09\x09\x09\x09 \x20\x09\x20\x09\x20\x09\x20\x20
</example>
and is followed by one or more of the following sequences to indicate the
version of OTR which the client supports:
<example caption='OTR tag version 1'>
\x20\x09\x20\x09\x20\x20\x09\x20
</example>
Note that this version 1 tag must come before other version tags for
compatibility; it is, however, NOT RECOMMENDED to implement version 1 of
the OTR protocol.
<example caption='OTR tag version 2'>
\x20\x20\x09\x09\x20\x20\x09\x20
</example>
<example caption='OTR tag version 3'>
\x20\x20\x09\x09\x20\x20\x09\x09
</example>
</p>
<p>
When a client sees this special string in the body of a message stanza it
may choose to start an OTR session immediately, or merely indicate support
to the user and allow the user to manually start a session. This is done by
sending a message stanza containing an OTR query message in the body which
indicates the supported versions of OTR. In XMPP these are most commonly
version 2 and version 3, which would be indicated by a message stanza which
has a body that starts with the string:
<example caption='OTR query'>
?OTR?v23?
</example>
</p>
<p>
Any message which begins with the afforementioned string (note that the
version number[s] may be different), postfixed with a payload should be
decrypted as an OTR message. The initialization message should not contain
a payload, and should just be the initialization string by itself.
</p>
</section1>
<section1 topic='OTR Messages'>
<section2 topic='Construction and Decoding'>
<p>
Some clients in the wild have been known to insert XML in the
&lt;body&gt; node of a message. Clients that support OTR should tolerate
encrypted payloads which expand to unescaped XML, and treat it as plain
text.
</p>
</section2>
<section2 topic='Routing'>
<p>
XMPP is designed so that the client needs to know very little about where
and how a message will be routed. Generally, clients are encouraged to
send messages to the bare JID and allow the server to route the messages
as it sees fit. However, OTR requires that messages be sent to a
particular resource. Therefore clients SHOULD send OTR messages to a full
JID, possibly allowing the user to determine which resource they wish to
start an encrypted session with. Furthermore, if a client receives a
request to start an OTR session in a carboned message (due to a server
which does not support the aforementioned "private" directive, or a
client which does not set it), it SHOULD be silently ignored.
</p>
</section2>
<section2 topic='Processing Hints'>
<p>
&xep0334; defines a set of hints for how messages should be handled by
XMPP servers. These hints are not hard and fast rules, but suggestions
which the servers may or may not choose to follow. Best practice is to
include the following hints on all OTR messages:
<code><![CDATA[
<no-copy xmlns="urn:xmpp:hints"/>
<no-permanent-store xmlns="urn:xmpp:hints"/>
]]></code>
</p>
<p>
Similarly the "private" directive from &xep0280; should also be included
to indicate that carbons are not necessary (since no other resource will
be able to read the message):
<code><![CDATA[
<private xmlns="urn:xmpp:carbons:2"/>
]]></code>
All together, an example OTR message might look like this (with the
majority of the body stripped out for readability):
<example caption='OTR message with processing hints'><![CDATA[
<message
from='malvolio@stewardsguild.lit/countesshousehold'
to='olivia@countess.lit/veiled'>
<body>?OTR?v23?...</body>
<no-copy xmlns="urn:xmpp:hints"/>
<no-permanent-store xmlns="urn:xmpp:hints"/>
<private xmlns="urn:xmpp:carbons:2"/>
</message>
]]></example>
</p>
</section2>
</section1>
<section1 topic='Use in XMPP URIs'>
<p>
&rfc5122; defines a Uniform Resource Identifier (URI) and Internationalized
Resource Identifier (IRI) scheme for XMPP entities, and &xep0147; defines
various query components for use with XMPP URI's. When an entity has an
associated OTR fingerprint it's URI is often formed with "otr-fingerprint"
in the query string. Eg.
<example caption='OTR Fingerprint'>
xmpp:feste@allfools.lit?otr-fingerprint=AEA4D503298797D4A4FC823BC1D24524B4C54338
</example>
</p>
<p>
The &REGISTRAR; maintains a registry of queries and key-value pairs for use
in XMPP URIs at &QUERYTYPES;. As of the date this document was authored,
the 'otr-fingerprint' query string has not been formally defined and has
therefore is not officially recognized by the registrar.
</p>
</section1>
<section1 topic='Acknowledgements' anchor='acks'>
<p>
Thanks to Daniel Gultsch for his excellent
<link url='https://github.com/siacs/Conversations/blob/development/docs/observations.md'>
article
</link>
<note>
Daniel Gultsch (Retreived on 2015-07-29). "Observations on Imlementing
XMPP"
&lt;<link url='https://github.com/siacs/Conversations/blob/development/docs/observations.md'>
https://github.com/siacs/Conversations/blob/development/docs/observations.md
</link>&gt;
</note>
on the pitfalls of implementing OTR, and to Georg Lukas for his feedback.
</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>
While this document describes an existing protocol which is streamed over
XMPP and therefore does not introduce any new security concerns itself, it
is worth mentioning a few security issues with the underlying OTR protocol:
</p>
<p>
Because Diffie-Hellman (D-H) key exchange is unauthenticated, the initial
D-H exchange which sets up the encrypted channel is vulnerable to a
man-in-the-middle attack. No sensitive information should be sent over the
encrypted channel until mutual authentication has been performed
inside the encrypted channel.
</p>
<p>
OTR makes use of the SHA-1 hash algorithm. While no practical attacks have
been observed in SHA-1 at the time of this writing, theoretical attacks
have been constructed, and attacks have been performed on hash functions
that are similar to SHA-1. One cryptographer estimated that the cost
of generating SHA-1 collisions was $2.77 million dollars in 2012, and would
drop to $700,000 by 2015.
<note>
Bruce Schneier (2012-10-05). "When Will We See Collisions for SHA-1?"
&lt;<link url='https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html'>
https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html
</link>&gt;
</note>.
This puts generating SHA-1 collisions well within the reach of governments,
malicious organizations, and even well-funded individuals.
</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>
This document requires no interaction with the Internet Assigned Numbers
Authority (IANA).
</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<p>
No namespaces or parameters need to be registered with the XMPP Registrar
as a result of this document.
</p>
</section1>
</xep>

138
xep-0365.xml Normal file
View File

@ -0,0 +1,138 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Server to Server communication over STANAG 5066 ARQ</title>
<abstract>
This specification defines operation over XMPP over the NATO STANAG 5066 data link service for point to point links (ARQ). This enables optimized XMPP performance over HF Radio (which STANAG 5066 was designed for) and over other data links using STANAG 5066.
</abstract>
&LEGALNOTICE;
<number>0365</number>
<status>Experimental</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XEP 0361</spec>
<spec>STANAG 5066</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>S5066</shortname>
<author>
<firstname>Steve</firstname>
<surname>Kille</surname>
<email>steve.kille@isode.com</email>
<jid>steve.kille@isode.com</jid>
</author>
<revision>
<version>0.1</version>
<date>2015-09-17</date>
<initials>XEP Editor (mam)</initials>
<remark><p>Initial published version approved by the XMPP Council.</p></remark>
</revision>
<revision>
<version>0.0.1</version>
<date>2015-08-19</date>
<initials>sek</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>
This specification arose from requirements to operate over HF Radio, which has exceedingly high latency (sometimes minutes) low data rates (down to 75 bits/second) and poor reliablity. <span class='ref'><link url='http://nso.nato.int/nso/zPublic/stanags/CURRENT/5066Ed03.pdf'>STANAG 5066</link></span> <note>STANAG 5066 C3B (EDITION 3): PROFILE FOR HF RADIO DATA COMMUNICATIONS &lt;<link url='http://nso.nato.int/nso/zPublic/stanags/CURRENT/5066Ed03.pdf'>http://nso.nato.int/nso/zPublic/stanags/CURRENT/5066Ed03.pdf</link>&gt;.</note>
is a widely used link level protocol. Direct use of <strong>STANAG 5066</strong> enables elimination of all extraneous end to end handshaking, which is important to optimize performance. It also enables use of <strong>STANAG 5066</strong> flow control, which is important for reslience.
</p>
<p>
The solution is based on &xep0361; and requires peer configuration to be established according to <strong>XEP-0361</strong>. The data exchanged between the XMPP servers follows exactly what is specified in <strong>XEP-0361</strong>. The data is transferred using <strong>STANAG 5066</strong> rather than using TCP.
</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<p>
This specification can be considered as a profile for server to server XMPP communication, to enable XMPP deployment over HF Radio using <strong>STANAG 5066</strong>. This profile MUST only be used where its use has been pre-agreed and configured for both participating servers.
</p>
</section1>
<section1 topic='Use Cases' anchor='usecases'>
<p>
An example scenario where this protocol is important is where two ships connected by HF Surface Wave communication only need to exchange XMPP messages. A reliable link (Soft Link) can be established using <strong>STANAG 5066</strong> and XMPP communicated efficiently and reliably.
</p>
</section1>
<section1 topic='Business Rules' anchor='rules'>
<section2 topic="General Operation">
<p>
Because of potentially very low bandwidth sending server MAY perform traffic optimisation, such as selective removal of stanzas that are not adding sufficient value, like CSNs, or strip selected elements such as xhtml-im.
</p>
<p>
Applications sending data over <strong>STANAG 5066</strong> need to be aware of increased delays and any application level timers (e.g., IQ response timers) need to be set accordingly.
</p>
</section2>
<section2 topic="Stream Fragmentation">
<p>
<strong>XEP-0361</strong> transfer of data between a pair of XMPP servers is a byte stream flowing in each direction over TCP. There is no other protocol or hand shaking.
When carried instead over <strong>STANAG 5066</strong>, these byte streams are transmitted as a sequence of blocks transferred in order
Each block is an XML stanza, holding message, presence or iq. Essentially the stream is broken into blocks (stanzas) at natural boundaries XMPP boundaries, and then reassembled on reception into the original stream.
</p>
<p>
&xep0198; MUST not be used over <strong>STANAG 5066</strong>, as reliability of stanza transfer is handled by use of <strong>STANAG 5066</strong>. Application-layer keepalives and timeout detection such as white-space pings and &xep0199; MUST NOT be used.
</p>
</section2>
<section2 topic="Mapping onto STANAG 5066">
<p>
Each stanza is transferred using the RCOP (Reliable Connection Oriented Protocol) defined in Section F.8 of Annex F of <strong>STANAG 5066</strong>. This reliably transfers the block of data to the destination. If a soft link needs to be established this will be done by the <strong>STANAG 5066</strong> service. The <strong>XEP-0361</strong> peer agreement is supported by a flow of stanzas in each direction being transferred by RCOP. The peer agreement will use this flow of stanzas to provide a service equivalent to the TCP connection or connections of <strong>XEP-0361</strong>.
</p>
<p>
<strong>STANAG 5066</strong> SIS Delivery Confirmation MAY be set to NODE DELIVERY, as this gives optimum network performance. CLIENT DELIVERY MAY be used, which increases reliability as stanza delivery to the peer XMPP server is guaranteed and the sending server will receive acknowledgements equivalent to <strong>XEP-0361</strong> support. In the event of delivery failure, the whole RCOP PDU (Stanza) MUST be retransmitted.
</p>
</section2>
<section2 topic="Addressing">
<p>
The peer addressing of the <strong>STANAG 5066</strong> end points will be configured as part of the <strong>XEP-0361</strong> peer agreement.
</p>
<p>
The <strong>STANAG 5066</strong> SAP MAY be set to any mutually agreed value. It is RECOMMENDED that 2 is used. This is the standard SAP for RCOP.
</p>
<p>
The RCOP connection ID number will be set to a mutually agreed value. It is RECOMMENDED that 0 is used as the preferred value.
</p>
</section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>
Security Considerations of <strong>XEP-0361</strong> apply. <strong>STANAG 5066</strong> will frequently be employed in conjunction with link level crypto devices, which SHOULD be done when appropriate to provide data confidentiality.
</p>
</section1>
<section1 topic='STANAG 5066 Standard' anchor='iana'>
<p>This specification uses STANAG 5066 Edition 3 "PROFILE FOR HF RADIO DATA COMMUNICATIONS" (December 2010). </p>
<p><strong>STANAG 5066</strong> is a NATO UNCLASSIFED (Releasable to the Public) document that may circulated freely. It is available on <link url='http://nso.nato.int/nso/zPublic/stanags/CURRENT/5066Ed03.pdf'>http://nso.nato.int/nso/zPublic/stanags/CURRENT/5066Ed03.pdf</link>.</p>
</section1>
<section1 topic="Acknowledgements">
<p>
Curtis King designed and validated the approach documented in this XEP.
</p>
<p>
Kevin Smith provided useful comments on this specification.
</p>
<p>
Dave Cridland asked NATO about STANAG 5066 publication, leading to its availability on the Web.
</p>
</section1>
</xep>

25
xep.ent
View File

@ -308,8 +308,8 @@ THE SOFTWARE.
<!ENTITY w3xml "<span class='ref'><link url='http://www.w3.org/TR/REC-xml/'>XML 1.0</link></span> <note>Extensible Markup Language (XML) 1.0 (Fourth Edition) &lt;<link url='http://www.w3.org/TR/REC-xml/'>http://www.w3.org/TR/REC-xml/</link>&gt;.</note>" >
<!ENTITY w3xmlenc "<span class='ref'><link url='http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/'>XML Encryption</link></span> <note>XML Encryption Syntax and Processing &lt;<link url='http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/'>http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/</link>&gt;.</note>" >
<!ENTITY w3xmlnamespaces "<span class='ref'><link url='http://www.w3.org/TR/REC-xml-names/'>Namespaces in XML</link></span> <note>Namespaces in XML &lt;<link url='http://www.w3.org/TR/REC-xml-names/'>http://www.w3.org/TR/REC-xml-names/</link>&gt;.</note>" >
<!ENTITY w3xmlschema1 "<span class='ref'><link url='http://www.w3.org/TR/xmlschema-1/'>XML Schema Part 1</link></span> <note>XML Schema Part 1: Structures &lt;<link url='http://www.w3.org/TR/xmlschema-1/'>http://www.w3.org/TR/xmlschema-1/</link>&gt;.</note>" >
<!ENTITY w3xmlschema2 "<span class='ref'><link url='http://www.w3.org/TR/xmlschema-2/'>XML Schema Part 2</link></span> <note>XML Schema Part 2: Datatypes &lt;<link url='http://www.w3.org/TR/xmlschema-2/'>http://www.w3.org/TR/xmlschema-2/</link>&gt;.</note>" >
<!ENTITY w3xmlschema1 "<span class='ref'><link url='http://www.w3.org/TR/xmlschema11-1/'>XML Schema Part 1</link></span> <note>XML Schema Part 1: Structures &lt;<link url='http://www.w3.org/TR/xmlschema11-1/'>http://www.w3.org/TR/xmlschema11-1/</link>&gt;.</note>" >
<!ENTITY w3xmlschema2 "<span class='ref'><link url='http://www.w3.org/TR/xmlschema11-2/'>XML Schema Part 2</link></span> <note>XML Schema Part 2: Datatypes &lt;<link url='http://www.w3.org/TR/xmlschema11-2/'>http://www.w3.org/TR/xmlschema11-2/</link>&gt;.</note>" >
<!ENTITY w3xmlsig "<span class='ref'><link url='http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/'>XML Signature</link></span> <note>XML Signature Syntax and Processing &lt;<link url='http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/'>http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/</link>&gt;.</note>" >
<!ENTITY w3xop "<span class='ref'><link url='http://www.w3.org/TR/xop10/'>XML-binary Optimized Packaging</link></span> <note>XML-binary Optimized Packaging &lt;<link url='http://www.w3.org/TR/xop10/'>http://www.w3.org/TR/xop10/</link>&gt;.</note>" >
<!ENTITY w3xpath "<span class='ref'><link url='http://www.w3.org/TR/xpath'>XPath</link></span> <note>XML Path Language &lt;<link url='http://www.w3.org/TR/xpath'>http://www.w3.org/TR/xpath</link>&gt;.</note>" >
@ -405,6 +405,7 @@ THE SOFTWARE.
<!ENTITY rfc1939 "<span class='ref'><link url='http://tools.ietf.org/html/rfc1939'>RFC 1939</link></span> <note>RFC 1939: Post Office Protocol - Version 3 &lt;<link url='http://tools.ietf.org/html/rfc1939'>http://tools.ietf.org/html/rfc1939</link>&gt;.</note>" >
<!ENTITY rfc1945 "<span class='ref'><link url='http://tools.ietf.org/html/rfc1945'>RFC 1945</link></span> <note>RFC 1945: Hypertext Transfer Protocol -- HTTP/1.0 &lt;<link url='http://tools.ietf.org/html/rfc1945'>http://tools.ietf.org/html/rfc1945</link>&gt;.</note>" >
<!ENTITY rfc1950 "<span class='ref'><link url='http://tools.ietf.org/html/rfc1950'>RFC 1950</link></span> <note>RFC 1950: ZLIB Compressed Data Format Specification version 3.3 &lt;<link url='http://tools.ietf.org/html/rfc1950'>http://tools.ietf.org/html/rfc1950</link>&gt;.</note>" >
<!ENTITY rfc1951 "<span class='ref'><link url='http://tools.ietf.org/html/rfc1951'>RFC 1951</link></span> <note>RFC 1951: DEFLATE Compressed Data Format Specification version 1.3 &lt;<link url='http://tools.ietf.org/html/rfc1951'>http://tools.ietf.org/html/rfc1951</link>&gt;.</note>" >
<!ENTITY rfc2026 "<span class='ref'><link url='http://tools.ietf.org/html/rfc2026'>RFC 2026</link></span> <note>RFC 2026: The Internet Standards Process &lt;<link url='http://tools.ietf.org/html/rfc2026'>http://tools.ietf.org/html/rfc2026</link>&gt;.</note>" >
<!ENTITY rfc2045 "<span class='ref'><link url='http://tools.ietf.org/html/rfc2045'>RFC 2045</link></span> <note>RFC 2045: Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies &lt;<link url='http://tools.ietf.org/html/rfc2045'>http://tools.ietf.org/html/rfc2045</link>&gt;.</note>" >
<!ENTITY rfc2068 "<span class='ref'><link url='http://tools.ietf.org/html/rfc2068'>RFC 2068</link></span> <note>RFC 2068: Hypertext Transport Protocol -- HTTP/1.1 &lt;<link url='http://tools.ietf.org/html/rfc2068'>http://tools.ietf.org/html/rfc2068</link>&gt;.</note>" >
@ -536,6 +537,7 @@ THE SOFTWARE.
<!ENTITY rfc4103 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4103'>RFC 4103</link></span> <note>RFC 4103: RTP Payload for Text Conversation &lt;<link url='http://tools.ietf.org/html/rfc4103'>http://tools.ietf.org/html/rfc4103</link>&gt;.</note>" >
<!ENTITY rfc4119 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4119'>RFC 4119</link></span> <note>RFC 4119: A Presence-based GEOPRIV Location Object Format &lt;<link url='http://tools.ietf.org/html/rfc4119'>http://tools.ietf.org/html/rfc4119</link>&gt;.</note>" >
<!ENTITY rfc4120 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4120'>RFC 4120</link></span> <note>RFC 4120: The Kerberos Network Authentication Service (V5) &lt;<link url='http://tools.ietf.org/html/rfc4120'>http://tools.ietf.org/html/rfc4120</link>&gt;.</note>" >
<!ENTITY rfc4121 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4121'>RFC 4121</link></span> <note>RFC 4121: The Kerberos Version 5 Generic Security Service Application Program Interface (GSS-API) Mechanism: Version 2 &lt;<link url='http://tools.ietf.org/html/rfc4121'>http://tools.ietf.org/html/rfc4121</link>&gt;.</note>" >
<!ENTITY rfc4122 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4122'>RFC 4122</link></span> <note>RFC 4122: A Universally Unique IDentifier (UUID) URN Namespace &lt;<link url='http://tools.ietf.org/html/rfc4122'>http://tools.ietf.org/html/rfc4122</link>&gt;.</note>" >
<!ENTITY rfc4145 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4145'>RFC 4145</link></span> <note>RFC 4145: TCP-Based Media Transport in the Session Description Protocol (SDP) &lt;<link url='http://tools.ietf.org/html/rfc4145'>http://tools.ietf.org/html/rfc4145</link>&gt;.</note>" >
<!ENTITY rfc4227 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4227'>RFC 4227</link></span> <note>RFC 4227: Using the Simple Object Access Protocol (SOAP) in Blocks Extensible Exchange Protocol (BEEP) &lt;<link url='http://tools.ietf.org/html/rfc4227'>http://tools.ietf.org/html/rfc4227</link>&gt;.</note>" >
@ -579,6 +581,7 @@ THE SOFTWARE.
<!ENTITY rfc4848 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4848'>RFC 4848</link></span> <note>RFC 4848: Domain-Based Application Service Location Using URIs and the Dynamic Delegation Discovery Service (DDDS) &lt;<link url='http://tools.ietf.org/html/rfc4848'>http://tools.ietf.org/html/rfc4848</link>&gt;.</note>" >
<!ENTITY rfc4854 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4854'>RFC 4854</link></span> <note>RFC 4854: A Uniform Resource Name (URN) Namespace for Extensions to the Extensible Messaging and Presence Protocol (XMPP) &lt;<link url='http://tools.ietf.org/html/rfc4854'>http://tools.ietf.org/html/rfc4854</link>&gt;.</note>" >
<!ENTITY rfc4880 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4880'>RFC 4880</link></span> <note>RFC 4880: OpenPGP Message Format &lt;<link url='http://tools.ietf.org/html/rfc4880'>http://tools.ietf.org/html/rfc4880</link>&gt;.</note>" >
<!ENTITY rfc4975 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4975'>RFC 4975</link></span> <note>RFC 4975: The Message Session Relay Protocol (MSRP) &lt;<link url='http://tools.ietf.org/html/rfc4975'>http://tools.ietf.org/html/rfc4975</link>&gt;.</note>" >
<!ENTITY rfc4949 "<span class='ref'><link url='http://tools.ietf.org/html/rfc4949'>RFC 4949</link></span> <note>RFC 4949: Internet Security Glossary, Version 2 &lt;<link url='http://tools.ietf.org/html/rfc4949'>http://tools.ietf.org/html/rfc4949</link>&gt;.</note>" >
<!ENTITY rfc5023 "<span class='ref'><link url='http://tools.ietf.org/html/rfc5023'>RFC 5023</link></span> <note>RFC 5023: The Atom Publishing Protocol &lt;<link url='http://tools.ietf.org/html/rfc5023'>http://tools.ietf.org/html/rfc5023</link>&gt;.</note>" >
<!ENTITY rfc5054 "<span class='ref'><link url='http://tools.ietf.org/html/rfc5054'>RFC 5054</link></span> <note>RFC 5054: Using the Secure Remote Password (SRP) Protocol for TLS Authentication &lt;<link url='http://tools.ietf.org/html/rfc5054'>http://tools.ietf.org/html/rfc5054</link>&gt;.</note>" >
@ -876,7 +879,8 @@ IANA Service Location Protocol, Version 2 (SLPv2) Templates</link></span> <note>
<author>
<firstname>Dave</firstname>
<surname>Cridland</surname>
<email>dave@cridland.net</email>
<email>dave.cridland@surevine.com</email>
<jid>dave.cridland@surevine.com</jid>
</author>
" >
<!ENTITY fabio "
@ -982,6 +986,15 @@ IANA Service Location Protocol, Version 2 (SLPv2) Templates</link></span> <note>
<email>winfried@tilanus.com</email>
</author>
" >
<!ENTITY sam "
<author>
<firstname>Sam</firstname>
<surname>Whited</surname>
<email>sam@samwhited.com</email>
<jid>sam@samwhited.com</jid>
<uri>https://blog.samwhited.com/</uri>
</author>
" >
<!-- XMPP Extension Protocols -->
@ -1337,8 +1350,12 @@ IANA Service Location Protocol, Version 2 (SLPv2) Templates</link></span> <note>
<!ENTITY xep0354 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0354.html'>Customizable Message Routing (XEP-0354)</link></span> <note>XEP-0354: Customizable Message Routing &lt;<link url='http://xmpp.org/extensions/xep-0354.html'>http://xmpp.org/extensions/xep-0354.html</link>&gt;.</note>" >
<!ENTITY xep0355 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0355.html'>Namespace Delegation (XEP-0355)</link></span> <note>XEP-0355: Namespace Delegation &lt;<link url='http://xmpp.org/extensions/xep-0355.html'>http://xmpp.org/extensions/xep-0355.html</link>&gt;.</note>" >
<!ENTITY xep0356 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0356.html'>Privileged Entity (XEP-0356)</link></span> <note>XEP-0356: Privileged Entity &lt;<link url='http://xmpp.org/extensions/xep-0356.html'>http://xmpp.org/extensions/xep-0356.html</link>&gt;.</note>" >
<!ENTITY xep0357 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0357.html'>Push (XEP-0357)</link></span> <note>XEP-0357: Push &lt;<link url='http://xmpp.org/extensions/xep-0357.html'>http://xmpp.org/extensions/xep-0357.html</link>&gt;.</note>" >
<!ENTITY xep0357 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0357.html'>Push Notifications (XEP-0357)</link></span> <note>XEP-0357: Push Notifications &lt;<link url='http://xmpp.org/extensions/xep-0357.html'>http://xmpp.org/extensions/xep-0357.html</link>&gt;.</note>" >
<!ENTITY xep0358 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0358.html'>Publishing Available Jingle Sessions (XEP-0358)</link></span> <note>XEP-0358: Publishing Available Jingle Sessions &lt;<link url='http://xmpp.org/extensions/xep-0358.html'>http://xmpp.org/extensions/xep-0358.html</link>&gt;.</note>" >
<!ENTITY xep0359 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0359.html'>Unique and Stable Stanza IDs (XEP-0359)</link></span> <note>XEP-0359: Unique and Stable Stanza IDs &lt;<link url='http://xmpp.org/extensions/xep-0359.html'>http://xmpp.org/extensions/xep-0359.html</link>&gt;.</note>" >
<!ENTITY xep0360 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0360.html'>Nonzas (are not Stanzas) (XEP-0360)</link></span> <note>XEP-0360: Nonzas (are not Stanzas) &lt;<link url='http://xmpp.org/extensions/xep-0360.html'>http://xmpp.org/extensions/xep-0360.html</link>&gt;.</note>" >
<!ENTITY xep0361 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0361.html'>Zero Handshake Server to Server Protocol (XEP-0361)</link></span> <note>XEP-0361: Zero Handshake Server to Server Protocol &lt;<link url='http://xmpp.org/extensions/xep-0361.html'>http://xmpp.org/extensions/xep-0361.html</link>&gt;.</note>" >
<!ENTITY xep0362 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0362.html'>Raft over XMPP (XEP-0362)</link></span> <note>XEP-0362: Raft over XMPP &lt;<link url='http://xmpp.org/extensions/xep-0362.html'>http://xmpp.org/extensions/xep-0362.html</link>&gt;.</note>" >
<!ENTITY xep0363 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0363.html'>HTTP File Upload (XEP-0363)</link></span> <note>XEP-0363: HTTP File Upload &lt;<link url='http://xmpp.org/extensions/xep-0363.html'>http://xmpp.org/extensions/xep-0363.html</link>&gt;.</note>" >
<!ENTITY xep0364 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0364.html'>Current Off-the-Record Messaging Usage (XEP-0364)</link></span> <note>XEP-0364: Current Off-the-Record Messaging Usage &lt;<link url='http://xmpp.org/extensions/xep-0364.html'>http://xmpp.org/extensions/xep-0364.html</link>&gt;.</note>" >
<!ENTITY xep0365 "<span class='ref'><link url='http://xmpp.org/extensions/xep-0365.html'>Server to Server communication over STANAG 5066 ARQ (XEP-0365)</link></span> <note>XEP-0365: Server to Server communication over STANAG 5066 ARQ &lt;<link url='http://xmpp.org/extensions/xep-0365.html'>http://xmpp.org/extensions/xep-0365.html</link>&gt;.</note>" >

View File

@ -2,7 +2,7 @@
<!--
Copyright (c) 1999 - 2014 XMPP Standards Foundation
Copyright (c) 1999 - 2015 XMPP Standards Foundation
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and
@ -131,7 +131,7 @@ OR OTHER DEALINGS IN THE SOFTWARE.
</xsl:if>
<tr valign='top'>
<td><strong>Copyright:</strong></td>
<td>&#169; 1999 - 2014 XMPP Standards Foundation. <a href='#appendix-legal'>SEE LEGAL NOTICES</a>.</td>
<td>&#169; 1999 - 2015 XMPP Standards Foundation. <a href='#appendix-legal'>SEE LEGAL NOTICES</a>.</td>
</tr>
<tr valign='top'>
<td><strong>Status:</strong></td>
@ -169,7 +169,7 @@ OR OTHER DEALINGS IN THE SOFTWARE.
<p style='color:green'>NOTICE: This Procedural document defines a process or activity of the XMPP Standards Foundation (XSF) that has been approved by the XMPP Council and/or the XSF Board of Directors. The XSF is currently following the process or activity defined herein and will do so until this document is deprecated or obsoleted.</p>
</xsl:if>
<xsl:if test='$thestatus = "Deferred"'>
<p style='color:red'>WARNING: Consideration of this document has been <strong>Deferred</strong> by the XMPP Standards Foundation. Implementation of the protocol described herein is not recommended.</p>
<p style='color:red'>WARNING: This document has been automatically Deferred after 12 months of inactivity in its previous Experimental state. Implementation of the protocol described herein is not recommended for production systems. However, exploratory implementations are encouraged to resume the standards process.</p>
</xsl:if>
<xsl:if test='$thestatus = "Deprecated"'>
<p style='color:red'>WARNING: This document has been <strong>Deprecated</strong> by the XMPP Standards Foundation. Implementation of the protocol described herein is not recommended. Developers desiring similar functionality are advised to implement the protocol that supersedes this one (if any).</p>

154
xmpp.css Executable file
View File

@ -0,0 +1,154 @@
BODY {
background-color: #ffffff;
color: #000000;
font-family: Verdana, Arial, Helvetica, Geneva, sans-serif;
font-size: small;
line-height: 130%;
margin-left: 7%;
margin-right: 7%;
}
#left {
border: 0px;
border-color: #aaaaaa;
border-right: 1px;
border-style: solid;
float: left;
margin: 0% 0% 5% 0%;
padding: 4px 2% 10px 2%;
width: 12%;
}
#main {
border: 0px;
color: #000000;
font-weight: normal;
margin: 0% 0% 5% 17%;
padding: 4px 2% 10px 2%;
text-decoration: none;
}
#foot {
border-top: 0px solid;
clear: both;
color: #666666;
font-size: x-small;
font-weight: normal;
text-align: center;
text-decoration: none;
}
A:link {
color: #336699;
}
A.standardsButton {
background-color: #ff6600;
border: 1px solid;
border-color: #ffc8a4 #7d3302 #3f1a01 #ff9a57;
color: #ffffff;
padding: 0px 3px 0px 3px;
text-decoration: none;
margin: 0px;
}
A:visited {
color: #663399;
}
H1, H2, H3, H4, H5, H6 {
color: #336699;
line-height: 0.8;
}
pre {
font-family: Courier, monospace;
}
ul {
list-style: disc outside;
}
.body {
font-family: Verdana, Arial, Helvetica, Geneva, sans-serif;
font-size: small;
}
.bold {
font-weight: bold;
}
.box {
border: thin dotted;
padding-bottom: 1em;
padding-left: 2em;
padding-right: 2em;
padding-top: 1em;
}
.caption {
font-weight: bold;
}
.code {
font-family: "Courier New", Courier, monospace;
white-space: pre;
}
.def {
text-indent: -6.3em;
padding-bottom: 1em;
padding-left: 6.5em;
padding-right: 10em;
padding-top: 1em;
}
.em {
font-style: italic;
}
.example {
background-color: yellow;
margin-left: 5%;
margin-right: 25%;
}
.indent {
padding-left: 5%;
padding-right: 5%;
}
.head {
color: #336699;
font-weight: bold;
}
.highlight {
color: #336699;
}
.nav {
font-size: small;
line-height: 45%;
text-decoration: none;
white-space: nowrap;
}
.navhead {
color: #336699;
font-size: medium;
line-height: 90%;
padding-left: 0px;
text-decoration: none;
}
.pagehead {
color: #336699;
text-decoration: none;
}
A:visited.pagehead {
color: #336699;
text-decoration: none;
}
.ref {
font-weight: bold;
}
.strong {
font-weight: bold;
}
.subhead {
font-style: italic;
}
.sub {
font-size: xx-small;
vertical-align: sub;
}
.super {
font-size: xx-small;
vertical-align: super;
}
.tablebody {
font-family: Verdana, Arial, Helvetica, Geneva, sans-serif;
font-size: small;
white-space: nowrap;
}
.event {
color: #336699;
}