IMUnified - Protokoll

Tagged as DE · net

Written on

IMUnified hat vor etwa zwei Jahren angekündigt, ein Protokoll zu schaffen, das es ermöglichen soll, verschiedene Instant Messaging Systeme mit einem Client zu benutzen. Gründungsmitglieder waren unter anderem MSN, Odigo und Yahoo!.

Inzwischen ist es wieder ruhig geworden, ob IMU jemals ernsthaft eingesetzt wird, wird wage ich fast zu bezweifeln. Aber immerhin kann beispielsweise der Yahoo!-Messenger das Protokoll, man muss es nur mit ein paar Registry-Änderungen unter Windows einschalten. Danach hat man die Möglichkeit, sich zusätzlich zu Yahoo! auch in andere IM Dienste anzumelden.

Dies habe ich zum Anlass genommen, mir IM Unified doch einmal anzuschauen und habe ein paar Sessions mit einem Network-Sniffer protokolliert. Das Protokoll ist an sich sehr einfach aufgebaut und erinnert etwas an Protokolle wie SMTP oder HTTP.

Alle Daten werden über eine TCP/IP-Verbindung ausgetauscht. Der Client konnektiert hierzu auf den Port 11319 des Servers. Über diese Verbindung macht er zunächst ein Login-Handshake und tauscht danach Daten aus. Der Austausch erfolgt in Blöcken.

Diese Blöcke haben dabei eine Zeilenstruktur, jede Zeile wird durch \r\n (carriage return, line feed) abgeschlosssen. Die erste Zeile enthält den Typ des Blockes, er gibt die Art des Befehles an. In der zweiten Zeile steht eine ASCII-Dezimalzahl, die angibt, wie viele Bytes der Block (gerechnet ab der dritten Zeile) enthält. Ab der dritten Zeile stehen Parameter-Zeilen, optional gefolgt von einer leeren Zeile zum Abschluss der Headerzeilen, optional gefolgt von einem Body des Blockes (z.B. in Nachrichten-Blöcken). Der Yahoo!-Messenger scheint die leere Zeile grundsätzlich zu übertragen, auch wenn kein Body benötigt wird, der Odigo-Server scheint die Leerzeile nur zu übermitteln, wenn der Body nicht leer ist.

Blocktypen (also Inhalt der ersten Zeile) habe ich bei der Nutzung von Odigo mit dem Yahoo!-Client dabei bisher folgende erhalten: "HELO" (vor Anmeldung, Versionsabsprache, Absprache über Authorisierungstyp), "LOGN Odigo-Nummer" (Austausch der eigentlichen Logininfo), "STAT status" (Setzen und empfangen eines Anwesenheitsstatus, z.B. STAT ONLINE), "ACK 600" (Bestätigung, keine Ahnung was die 600 bedeutet), "LIST ADD Odigo-Nummer" (Hinzufügen eines Nutzers), "PING" (Keep-Alive-Packets, Intervall bestimmt der Server in seinem HELO-Block), "MESG" (Nachricht), "LIST ACCEPT Odigo-Nummer" (Hinzufügen von sich selbst für einen Nutzer erlauben), "DISC" (Abmelden).

Die Kopfzeilen in einem Block haben immer das Format "Bezeichnung: Inhalt". Eine dabei immer enthaltene Kopfzeile ist die ID-Zeile. Sie identifiziert jeden Block eindeutig, der Server spiegelt die enthaltene ID in einer Reference-Kopfzeile, wenn sich ein Block direkt auf einen Block des Clients bezieht (z.B. bei "ACK 600"-Blöcken). Im Falle es Yahoo!-Messengers werden die IDs anscheinend immer als erste Kopfzeile gesendet und haben als Inhalt eine fortlaufende ASCII-Dezimalzahl ab 1001. Auch übermittelt der Yahoo!-Messenger die ID-Zeile immer als erste Kopfzeile. Dies ist vermutlich nicht notwendig, jedenfalls fügt der Odigo-Server seine ID-Zeile nicht immer als erste Kopfzeile ein.

Der erste vom Client zum Server übertragene Block ist ein "HELO"-Block, neben der ID-Zeile enthält dieser Block noch eine Protocol-Zeile ("Protocol: IMIP/1.0") sowie eine leere Zeile. Der Odigo-Server antwortet mit "Auth-Type: imip-md5", "Capabilities: server-lists", ID-Zeile, "Keep-Alive: 60", "Protocol: IMIP/1.0", "Registration: http://www.odigo.com/user", "Service: odigo.com", "ServiceDisplayName: Odigo", Leerzeile, ASCII-String (bei Odigo eine dezimale 32-Bit-ASCII-Zahl, als Salt für das Passwort). Die Zeilen scheinen recht eindeutig zu sein, die Keep-Alive-Zeile scheint zu steuern wie oft der Client einen PING-Block schickt. Der HELO-Block des Servers besitzt interessanterweise keine Reference-Zeile.

Danach sendet der Client einen "LOGN Odigo-Nummer"-Block. Die enthaltenen Zeilen sind: ID-Zeile, "Client: Yahoo! IMIP Client", "Auth-Type: imip-md5" und eine Leerzeile, danach kommt als Body eine 128-Bit-Zahl hexadezimal mit Kleinbuchstaben in ASCII-Darstellung. Diese Zahl ist der md5-Hash des Strings, der durch direktes aneinanderhängen des Salt-Strings aus dem HELO-Block des Servers und dem Passwort gebildet wird. An der UNIX-Kommandozeile kann dies mit dem m5sum-Befehl nachvollzogen werden. Der Wert für das Salt "1919833824" und das Passwort "Passwort" wird wie folgt berechnet: printf "1919833824Passwort" | md5sum. Der Server antwortet darauf mit einem "LOGN Odigo-Nummer"-Block. Kopfzeilen sind nur ID und Reference enthalten.

Anschließend setzt der Client sich online mit einem "STAT ONLINE"-Block, enthaltene Kopfzeilen: ID-Zeile und Leerzeile. Der Server antwortet mit einem "ACK 600"-Block, enthaltene Zeilen: ID und Reference. Andere Online-Stati sind "STAT BUSY", "STAT AWAY" und "STAT OFFLINE" (invisible). Dem Online-Status kann ein erklärender Text als Body des Blockes hinzugefügt werden.

Der Server informiert den Client über die Anwesenheit der Kontakte ebenfalls mit "STAT Status"-Blöcken. Enthaltene Kopfzeilen sind ID und "From: Odigo-Nummer". Es ist keine Leerzeile und kein Body enthalten. Auch bestätigt der Client den Empfang nicht.

Der Server setzt in seinem HELO-Block ein Intervall mit dem der Client PING-Blöcke sendet. Ein solcher Block enthält zwei Kopfzeilen: ID und eine leere. Der Server antwortet mit dem oben beschriebenen "ACK 600"-Block.

Eine abgehende Nachricht verschickt der Yahoo!-Messenger mit einem "MESG"-Block, der die folgenden Zeilen enthält: ID, "To: Odigo-Nummer", "ACK-Type: errors-only", "From: eigene Odigo-Nummer", Leerzeile gefolgt vom Nachrichtenbody. Vom Server kam keine Bestätigung, dies ist vermutlich über die ACK-Type-Zeile gesteuert.

Eine eingehende Nachricht wird ebenfalls in einem "MESG"-Block übertragen. Der Odigo-Server übermittelt dabei jedoch ein paar mehr Kopfzeilen als oben im "MESG"-Block des Clients. Enthalten sind: "Content-Type: text/plain;charset=utf-8", "From: Odigo-Nummer "Nickname"", ID-Zeile, "Time: yyyy-mm-ddThh:mm:ssZ" (Kleinbuchstaben im Datumsstring stehen für entsprechende Zahlen, Angabe in UTC), "To: eigene Odigo-Nummer", Leerzeile und der Nachricht im Body. Der Client bestätigt diesen Block nicht.

Die Abmeldung leitet der Client mit einem "DISC"-Block ein. Enthalten ist eine ID-Zeile und eine leere Zeile. Der Server bestätigt dies mit einem üblichen "ACK 600"-Block. Danach wird die Verbindung getrennt.

Auf die Kontaktliste wird ein Kontakt mit einem "LIST ADD Odigo-Nummer"-Block hinzugefügt. Enthaltene Kopfzeilen sind dabei: ID, "List: Buddy" (vermutlich Auswahl einer Gruppe), "From: Odigo-Nummer" und eine Leerzeile. Der Server antwortet sofort mit einem "ACK 600"-Block. Dass das Gegenüber die Sichtbarkeit erlaubt hat, erfährt man, indem man die Anwesenheit mit einem "STAT Online-Status"-Block übermittelt bekommt.

Wenn jemand einen selbst auf seine Kontaktliste hinzufügen möchte, so bekommt man einen "LIST ADD"-Block ohne Odigo-Nummer in der ersten Zeile. Enthaltene Kopfzeilen sind: "From: Odigo-Nummer "Nick-Name"", ID, "List: Buddy" (ich hatte den entsprechenden Kontakt in dieser Gruppe stehen), Leerzeile und der mit der Authorisierungsanforderung angegebene Text. Die Authorisierung wird mit einem "LIST ACCEPT Odigo-Nummer "Nick-Name""-Block angenommen. Enthaltene Kopfzeilen darin sind ID, From und eine Leerzeile. Der Server bestätigt dies mit einem "ACK 600"-Block.

Update: Ich vermute inzwischen, dass "List: Buddy" keine Gruppe ist, sondern es sich dabei um die Contact-List an sich handelt und andere Listen evtl. Invisible-List und dergleichen sein könnten. Ich habe hierzu jedoch noch keine weiteren Nachforschungen angestellt. Neu habe ich jedoch inzwischen herausgefunden, wie ein Kontakt von der Contact-List entfernt wird (Block des Typs "LIST REMOVE Odigo-Nummer" mit den Headern ID, "List: Buddy" und "From: Odigo-Nummer"; Bestätigung durch den Server mit einem "ACK 600"-Paket) und wie das Hinzufügen zur Contact-List abgelehnt wird (Block des Typs "LIST REJECT Odigo-Nummer" mit den Headern ID und "From: Odigo-Nummer").

Im LOGN-Block des Servers wird die Contact-List des Users gemeldet. Dies geschieht in der Header-Zeile Buddy, die eine Liste von Nutzern (und deren Nick-Name in Anführungszeichen) durch Kommata getrennt enthält.

Folgende weitere ACK-Statusnummern habe ich neben "ACK 600" bisher erhalten: 800 als ich einen STAT-Block ohne Status gesendet habe, 801 als ich einen STAT-Block mit ungültigem Status gesendet habe, 810 wenn ich beim Login ein falsches Passwort verwende, 811 wenn ich beim Login eine ungültige User-ID nutze oder an eine solche User-ID eine Nachricht schicke (die UserID war nicht numerisch, wie bei Odigo immer de Fall).

Einfache IMIP-Session als Beispiel, [Beispiel mit Nachrichtentasch und Subscription]/imu-session2), Testimplementierung eines einfachen Java-Odigo-Client auf IMIP-Basis.


Unless otherwise credited all material Creative Commons License by Matthias Wimmer