2.3 Autoryzacja (logowanie do sieci)
Po pomyślnym rozpoczęciu sesji pora na zalogowanie się do sieci Tlen.pl. Procedura autoryzacji została nieco zmieniona w stosunku do jabbera.
Dotychczas pakiet autoryzacji wyglądał tak:
<iq type="set" id="456C287C">
<query xmlns="jabber:iq:auth">
<username>malcom</username>
<digest>aab5c5f9a3eea18023d99405509fea968ada18ec</digest>
<resource>t</resource>
</query>
</iq>
Od wersji 9
protokołu, pakiet ten został wzbogacony o nazwę hosta:
<iq type="set" id="456C287C">
<query xmlns="jabber:iq:auth">
<username>malcom</username>
<digest>aab5c5f9a3eea18023d99405509fea968ada18ec</digest>
<resource>t</resource>
<host>tlen.pl</host>
</query>
</iq>
Wartość atrybutu id
to identyfikator sesji, jaki otrzymaliśmy przy nawiązywaniu połączenia. Tag username
zawiera nasz identyfikator tlenowy. W digest
znajduje się "hash" naszego hasła, o którym sobie jeszcze powiemy. Natomiast resource
określa zasób, niestety sieć Tlen.pl została pozbawiona tej funkcjonalności. Oryginalny klient wysyła wartość t
, aczkolwiek można użyć innej, "dobrowolnej" wartości. Element host
zawiera nazwę hosta serwera.
Wysyłany "hash" w digest
to "przepuszczony" przez SHA1 wynik połączenia identyfikatora sesji z 8-bitowym hashem hasła. Trochę to dziwne ;)
Hash hasła można wygenerować następującą funkcją języka C:
int calc_passcode(const char* pass, char* code) {
int magic1 = 0x50305735;
int magic2 = 0x12345671;
int sum = 7;
char z;
while ((z = *pass++) != 0) {
if (z == ' ') continue;
if (z == '\t') continue;
magic1 ^= (((magic1 & 0x3f) + sum) * z) + (magic1 << 8);
magic2 += (magic2 << 8) ^ magic1;
sum += z;
}
magic1 &= 0x7fffffff;
magic2 &= 0x7fffffff;
return sprintf(code, "%08x%08x", magic1, magic2);
} // end _calc_passcode();
Jeśli autoryzacja przebiegnie poprawnie, w odpowiedzi na pakiet autoryzacji otrzymamy:
<iq type="result" id="456C287C"/>
I tak oto zostaliśmy poprawnie autoryzowani do sieci komunikatora Tlen.pl ;)
W przypadku błędnej autoryzacji serwer odeśle nam pakiet:
<iq type="error" id="456C287C"/>
W takim wypadku możemy ponowić próbę autoryzacji, bądź zakończyć sesję wysyłając odpowiedni pakiet.
Uwaga!
Serwer sam nie zakończy sesji po nieudanej próbie zalogowania się, chyba, że nie będziemy podtrzymywać sesji, czyli odpowiednio "pingować" serwera ;)