This below needs to be cleaned up, checked, and reformatted yet...
Server Dialback Protocol ------------------------ Introduction: Dialback is a method of verifying that a connection between two servers can be trusted. Using DNS, one server can that another server which is connecting to it is authorized to represent a given jabber server network. It is thus used to prevent forgery; it prevents the spoofing a particular server name and sending false data from it. The primary reason for the complexity here is the existance of server farms: a simple reverse DNS or IP lookup will not work for a complex environment. Dialback originally went into the 1.2 server. It is not currently enforced, so that locations with 1.0 servers will have a window of upgrade. Vocabulary: - Server A : This is the originating server, the server which is attempting to establish a connection between the two servers (A and B) - Server B : This is the receiving server, which is trying to authenticate that Server A represents the jabber server which it claims - Authorative Server A : This is the authorative server, which is given when when a DNS lookup is performed on the server name A initially gave. For simple environments this will be A, in other environments this could be a separate machine in A's network. Overview: To briefly summarize the order of events in dialback: Server A establishes a connection to Server B Server A sends a 'key' value over the connection to B Server B establishes a connection to Authorative Server A Server B sends the same 'key' value to Authorative Server A Authoritive Server A responds whether the key works out to be Valid or Invalid Server B tells Server A whether they are authenticated or not Implementation: The traffic sent between the machines is as follows: 1. Server A establishes connection to B (Conn 1) 2. Server A sends a stream header to B over Conn 1: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:server' to='Server B' from='Server A' xmlns:db='jabber:server:dialback'> The xmlns:db actually indicates to server B that server A supports dialback at all. 2. Server B sends a stream header back to Server A over Conn 1: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:server' from='Server B' to='Server A' xmlns:db='jabber:server:dialback' id='457F9224A0...'> 3. Server A sends a dialback key to Server B over Conn 1: <db:result to='Server B' from='Server A'>98AF014EDC0...</db:result> Note that this key is not even examined by Server B; it does not keep information on Server A between sessions. 4. Server B now establishes a connection back to Server A, getting the Authorative Server A (Conn 2) 5. Server B sends Authorative Server A a stream header on Conn 2: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:server' from='Server B' to='Server A' xmlns:db='jabber:server:dialback'> 6. Authorative Server A sends Server B a stream header on Conn 2: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:server' to='Server B' from='Server A' xmlns:db='jabber:server:dialback' id='1251A342B...'> Note the presence of the id attribute: this will be explained further down. 7. Server B sends Authorative Server A a packet on Conn 2 indicating it wants wants Authorative Server A to verify a key: <db:verify from='Server B' to='Server A' id='457F9224A0...'>98AF014EDC0...</db:verify> Passed here are the server names, the original identifier from Server B's stream header to Server A in step 2, and the key Server A gave Server B in step 3. Based on this information and shared secret information within the 'Server A' network, the key is verified. The key generation technique used by the jabber.org 1.2 and 1.4 server uses a SHA1-hashed concatenation of a subset of this information, but the key is private to the servers making up the Server A network: any verifiable method can be used to generate the key. 8. Authorative Server A sends a packet back to Server B over Conn 2 indicating whether the key was valid or invalid: <db:result from='Server A' to='Server B' type='valid' id='457F9224A0...'/> or <db:result from='Server A' to='Server B' type='invalid' id='457F9224A0...'/> 9. Server B informs Server A of the result over Conn 1: <db:result from='Server B' to='Server A' type='valid'/> At this point the connection has either been validated via a type='valid', or reported as invalid. Once the connection is validated, data can be sent over Conn 1 and read by Server B; before that, packets are dropped. There is a small caveat which makes the above considerably harder to follow. When Server B and Authorative Server A are talking, Server B has the option of not only sending the db:verify request over, but sending a db:result over with its own key. After this, Authorative Server A would establish a connection with Authorative Server B to conduct the dialback again, this time in reverse (so that Server B can conduct server to server communication with Server A). The reason that Server B needs to do this is that s2s requires two sockets between servers. Remember again that the networks can be complicated server farms - there could be one authorative jabber server for handling s2s traffic, and this would need to be the one that Server B communicates with, not the Server A which established the connection