%ents;
]>
Per a vote of the Jabber Council, changed status to Deprecated. Per a vote of the Jabber Council, advanced status to Active. Changed format to allow socket-equivalent security. Initial version. Note Well: This protocol specified in this document has been superseded by the protocol specified in &xep0124;.
This specification documents a method to allow Jabber clients to access Jabber
servers from behind existing firewalls. Although several similar methods
have been proposed, this approach should work through all known firewall
configurations which allow outbound HTTP access.
In general, a firewall is a box that protects a network from outsiders,
by controlling the IP connections that are allowed to pass through the
box. Often, a firewall will also allow access outside only by proxy,
either explicit proxy support or implicit through Network Address
Translation (NAT).
In the interest of security, many firewall administrators do not allow
outbound connections to unknown and unused ports. Until Jabber becomes
more widely deployed, port 5222/tcp (for Jabber client connections) will
often be blocked.
The best solution for sites that are concerned about security is to run
their own Jabber server, either inside the firewall, or in a DMZ
In addition, many firewalls/proxy servers will also not allow or not
honor HTTP Keep-alives (as defined in section 19.7.1.1 of &rfc2068;)
and will consider long-lived socket connections as security issues.
Because of this the traditional Jabber connection model, where one
socket is one stream is one session, will not work reliably.
In light of all of the ways that default firewall rules can interfere
with Jabber connectivity, a lowest-common denominator approach was
selected. HTTP is used to send XML as POST requests and receieve pending
XML within the responses. Additional information is prepended in the
request body to ensure an equivalent level of security to TCP/IP sockets.
The client makes HTTP requests periodically to the server. Whenever the
client has something to send, that XML is included in the body of the
request. When the server has something to send to the client, it must be
contained in the body of the response.
In some browser/platform combinations, sending cookies from the client is
not possible due to design choices and limitations in the
browser. Therefore, a work-around was needed to support clients based on
these application platforms.
All requests to the server are HTTP POST requests, with Content-Type:
application/x-www-form-urlencoded. Responses from the server have
Content-Type: text/xml. Both the request and response bodies are UTF-8
encoded text, even if an HTTP header to the contrary exists. All
responses contain a Set-Cookie header with an identifier, which is sent
along with future requests as described below. This identifier cookie
must have a name of 'ID'. The first request to a server always uses 0 as
the identifier. The server must always return a 200 response code,
sending any session errors as specially-formatted identifiers.
The client sends requests with bodies in the following format:
Identifier
Purpose
identifier
To uniquely identify the session server-side. This field is only
used to identify the session, and provides no security.
key
To verify this request is from the originator of the session. The
client generates a new key in the manner described below for each
request, which the server then verifies before processing the
request.
new_key
The key algorithm can exhaust valid keys in a sequence, which
requires a new key sequence to be used in order to continue the
session. The new key is sent along with the last used key in the
old sequence.
xml_body
The body of text to send. Since a POST must be sent in order for
the server to respond with recent messages, a client may send
a request without an xml_body in order to just retrieve new
incoming packets. This is not required to be a full XML document or
XML fragment, it does not need to start or end on element boundaries.
The identifier is everything before the first semicolon, and must consist of the characters [A-Za-z0-9:-]. The identifier returned from the first request is the identifier for the session. Any new identifier that ends in ':0' indicates an error, with the entire identifier indicating the specific error condition. Any new identifier that does not end in ':0' is a server programming error, the client should discontinue the session. For new sessions, the client identifier is considered to be 0.
Any identifier that ends in ':0' indicates an error. Any previous identifier associated with this session is no longer valid.
Server returns ID=0:0. The response body can contain a textual error message.
Server returns ID=-1:0
Server returns ID=-2:0
Server returns ID=-3:0
The key is a client security feature to allow TCP/IP socket equivalent security. It does not protect against intermediary attacks, but does prevent a person who is capable of listening to the HTTP traffic from sending messages and receiving incoming traffic from another machine.
The key algorithm should be familiar with those with knowledge of Jabber zero-knowledge authentication.
Note: Base64 encoding is defined in &rfc3548;. SHA1 is defined in &rfc3174;.
No framing is implied by a single request or reply. A single request can have no content sent, in which case the body contains only the identifier followed by a comma. A reply may have no content to send, in which case the body is empty. Zero or more XMPP packets may be sent in a single request or reply, including partial XMPP packets.
The absense of a long-lived connection requires the server to consider client traffic as a heartbeat to keep the session alive. If a server-configurable period of time passes without a successful POST request sent by the client, the server must end the client session. Any client requests using the identifier associated with that now dead session must return an error of '0:0'.
The maximum period of time to keep a client session active without an incoming POST request is not defined, but five minutes is the recommended minimum. The maximum period of time recommended for clients between requests is two minutes; if the client has not sent any XML out for two minutes, a request without an XML body should be sent. If a client is disconnecting from the server, a closing <stream:stream> must be sent to end the session. Failure to do this may have the client continue to be represented to other users as available.
If the server disconnects the user do to a session timeout, the server MUST bounce pending IQ requests and either bounce or store offline incoming messages.
The following is the sequence used for client communication