Le Nabaztag, comment ca marche ? Partie 2 : l'authentification et la fin du boot

Nouvel épisode de notre série un nabaztag, comment ça marche. Cette fois-ci, nous allons nous attaquer à l'authentification, l'étape juste après la séquence de boot

A la fin de la première partie, nous avions vu que le lapin tentait de se connecter à un serveur XMPP (par défault xmpp.nabaztag.com). C'est sur ce serveur que se déroule l'étape d'authentification, constituée d'une série d'échanges entre le lapin et le serveur.

Etape 1 :

Le lapin envoie le message suivant au serveur :

LAPIN :
<?xml version='1.0' encoding='UTF-8'?>
<stream:stream to='xmpp.nabaztag.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>

Rien de particulier ici, le serveur répond alors :

SERVEUR :
<?xml version='1.0'?>
<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='1549628791' from='xmpp.nabaztag.com' version='1.0' xml:lang='en'>

Etape 2 :

Le serveur envoie alors les méthodes d'authentification disponibles :

SERVEUR :
<stream:features>
<mechanisms xmlns='urn:ietf: params:xml:ns:xmpp-sasl'>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
</mechanisms>
<register xmlns='http://violet.net/features/violet-register'/>
</stream:features>

Le lapin choisit de s'authentifier en MD5 par défaut :

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

Etape 3 :

La méthode d'authentification ayant été choisie, le serveur envoie donc un challenge pour que le lapin s'identifie :

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




Le serveur envoie ici son premier challenge encodé en Base64. Une fois décodée, la chaîne vaut :

nonce="1347617052",qop="auth",charset=utf-8,algorithm=md5-sess

(Les messages en Base64 ont volontairement été scindés en plusieurs partie à des fins de mise en page)

Le lapin doit alors répondre correctement pour continuer la séquence :

LAPIN :
<response xmlns='urn:ietf: params:xml:ns:xmpp-sasl'>
dXNlcm5hbWU9IjAwMTNkMzg0NTM1YSIsbm9uY2U9IjEzNDc2MTcwNTIiLGNub25
jZT0iMTQzMzIxNTY1MzU3Mu+/vSIsbmM9MDAwMDAwMDEscW9wPWF1dGgsZGl
nZXN0LXVyaT0ieG1wcC94bXBwLm5hYmF6dGFnLmNvbSIscmVzcG9uc2U9ZDYyN
GNlZmNlYWYzNjBhMzg3NDRjOWM1MTY1ZDZhYzcsY2hhcnNldD11dGYtOA==
</response>

Une fois encore, le message est encodé en Base64. Décodons-le :

username="0013d384535a",
nonce="1347617052",cnonce="1433215653572&#65533;",
nc=00000001,
qop=auth,digest-uri="xmpp/xmpp.nabaztag.com",
response=d624cefceaf360a38744c9c5165d6ac7,charset=utf-8

Examinons de plus près cette réponse du lapin. Il s'agit d'une authentification en mode DIGEST, où le username est l'adresse MAC du lapin.

Le but initial étant de construire un nouveau serveur pour les nabaztag, nous n'avons que peu à faire de l'authentification. Il suffit juste de faire croire au lapin que la séquence qu'il a envoyée est correcte ;)

Normalement, le serveur renvoie donc une réponse du type :

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

Où XXXX est de nouveau une chaîne encodée en base64 de la forme :

rspauth=HASH

(Le hash étant ici la réponse au DIGEST)

Etape 4 :

Le lapin demande alors si son authentification est correcte, de la manière la plus simple possible :

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

Il suffit alors au serveur de lui répondre OK :)

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

A partir de maintenant, le lapin est considéré comme authentifié auprès du serveur.
Nous n'avions donc pas besoin de calculer le hash pour le DIGEST, le lapin s'attendant juste à recevoir un <success /> pour continuer sa séquence de boot.

Les étapes qui suivent ne font pas partie à proprement parler de l'authentification, mais elles constituent la suite de la séquence d'initialisation du lapin. C'est à la fin de cette séquence que le lapin sera pleinement fonctionnel et attendra de nouvelles commandes.

Examinons tout ceci :

LAPIN :
<?xml version='1.0' encoding='UTF-8'?>
<stream:stream to='sackboylocal.eskuel.net' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>

Le lapin initie donc un nouveau Stream, comme au début de l'authentification.

SERVEUR :
<?xml version='1.0'?>
<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='1331400675' from='xmpp.nabaztag.com' version='1.0' xml:lang='en'>
<stream:features>
<bind xmlns='urn:ietf: params:xml:ns:xmpp-bind'>
<required/>
</bind>
<unbind xmlns='urn:ietf: params:xml:ns:xmpp-bind'/>
<session xmlns='urn:ietf: params:xml:ns:xmpp-session'/>
</stream:features>

Le lapin change alors sa resource XMPP, pour marquer qu'il est en mode boot :

LAPIN :
<iq from="0013d384535a@sackboylocal.eskuel.net/" to="xmpp.nabaztag.com" type='set' id='1'>
<bind xmlns='urn:ietf: params:xml:ns:xmpp-bind'>
<resource>boot</resource>
</bind>
</iq>

Le serveur accuse réception de ce changement :

SERVEUR :
<iq id='1' type='result'>
<bind xmlns='urn:ietf: params:xml:ns:xmpp-bind'>
<jid>0013d384535a@xmpp.nabaztag.com/boot</jid>
</bind>
</iq>

Démarrage de session avec cette nouvelle resource

LAPIN :
<iq from='0013d384535a@xmpp.nabaztag.com/boot' to='xmpp.nabaztag.com' type='set' id='2'>
<session xmlns='urn:ietf: params:xml:ns:xmpp-session'/>
</iq>

SERVEUR :
<iq type='result' to='0013d384535a@xmpp.nabaztag.com/boot' from='xmpp.nabaztag.com' id='2'>
<session xmlns='urn:ietf: params:xml:ns:xmpp-session'/>
</iq>

LAPIN :
<iq from='0013d384535a@xmpp.nabaztag.com/boot' to='net.violet.platform@xmpp.nabaztag.com/sources' type='get' id='3'>
<query xmlns="violet:iq:sources">
<packet xmlns="violet: packet" format="1.0"/>
</query>
</iq>

SERVEUR :
<iq from='net.violet.platform@xmpp.nabaztag.com/sources' to='0013d384535a@xmpp.nabaztag.com/boot' id='3' type='result'>
<query xmlns='violet:iq:sources'>
<packet xmlns='violet: packet' format='1.0' ttl='604800'>
fwQAAAx////+BAAFAA7/CAALAAABAP8=
</packet>
</query>
</iq>

Le serveur nous renvoie ici un paquet contenant l'état du lapin en fin de boot (à savoir les oreilles positionnées à la verticale). Le formatage de ces paquets fera l'objet d'un autre article.

LAPIN :
<iq from="0013d384535a@xmpp.nabaztag.com/boot" to="xmpp.nabaztag.com" type='set' id='4'>
<bind xmlns='urn:ietf: params:xml:ns:xmpp-bind'>
<resource>idle</resource>
</bind>
</iq>

Le lapin change de nouveau de resource pour passer en /idle

SERVEUR :
<iq id='4' type='result'>
<bind xmlns='urn:ietf: params:xml:ns:xmpp-bind'>
<jid>0013d384535a@xmpp.nabaztag.com/idle</jid>
</bind>
</iq>

Le serveur accuse réception. Comme précédemment, le lapin démarre alors une nouvelle session sur cette nouvelle resource

LAPIN :
<iq from='0013d384535a@xmpp.nabaztag.com/idle' to='xmpp.nabaztag.com' type='set' id='5'>
<session xmlns='urn:ietf: params:xml:ns:xmpp-session'/>
</iq>

Le serveur accuse réception :

SERVEUR :
<iq type='result' to='0013d384535a@xmpp.nabaztag.com/idle' from='xmpp.nabaztag.com' id='5'>
<session xmlns='urn:ietf: params:xml:ns:xmpp-session'/>
</iq>

LAPIN :
<presence from='0013d384535a@xmpp.nabaztag.com/idle' id='6'></presence>

SERVEUR :
<presence from='0013d384535a@xmpp.nabaztag.com/idle' id='6'></presence>

Le lapin peut alors libérer la resource /boot, maintenant qu'il a commencé une session en /idle

LAPIN :
<iq from='0013d384535a@xmpp.nabaztag.com/boot' to='xmpp.nabaztag.com' type='set' id='7'>
<unbind xmlns='urn:ietf: params:xml:ns:xmpp-bind'>
<resource>boot</resource>
</unbind>
</iq>

SERVEUR :
<iq id='7' type='result' />

Voilà, à partir de ce point, le lapin a terminé sa séquence de boot et d'authentification. Il est désormais prêt à recevoir des ordres de la part du serveur. Nous verrons dans le prochain article comment sont structurés les ordres envoyés au lapin.

Stay tuned !

Publié le :
18/08/2011
Dans la catégorie :
Auteur :
Mathieu LESNIAK
Mathieu LESNIAK
Commentaires :
juherr
juherr
Il y a un message du lapin qui est mal formaté.

Je ne me suis pas documenté sur XMPP mais je sais que Violet a fait quelques modifications sur le serveur qu'ils utilisaient (sans en donner les sources, ce serait trop simple sinon).
Est-ce que tu sais si le nab respecte le protocole (et si non, quels sont les messages non standards) ?
18/08/2011 11:07:05
Mathieu
Mathieu
Merci pour la relecture :)

A vrai dire, l'implémentation du XMPP par le lapin est assez rudimentaire. Je n'ai pas cherché à comparer ça au protocole XMPP standard, me doutant bien que la RFC ne serait pas respectée ;)
18/08/2011 11:11:23