Autoryzacja w Gadu Radio
• tech • 1415 słów • 7 minut czytania
Udało mi się wreszcie opisać sposób i algorytm autoryzacji w usłudze Gadu Radio. Wykorzystałem materiały udostępnione przez AQQKillera oraz własne analizy i spostrzeżenia wynikłe w czasie prac nad wtyczką “Gadu Radio” dla komunikatora Tlen.pl.
Wprowadzenie
Gadu Radio to najpopularniejsze polskie radio internetowe. Po raz pierwszy zaczęło nadawać we wrześniu 2006 roku. Obecnie słucha je już 250 tys. osób dziennie i ponad 1,2 mln osób miesięcznie.
Jest to typowa usługa internetowej rozgłośni radiowej nadająca swoje audycje przez Internet za pomocą przesyłania strumieniowego, wykorzystując odpowiednie oprogramowanie serwera mediów strumieniowych, w tym przypadku oprogramowania fundacji Xiph.org - Icecast.
Oczywiście w przypadku Gadu Radia nie wystarczy uruchomienie odtwarzacza i wprowadzenie adresu serwera strumieniowego, aby oddać się przyjemności słuchania radia. Trzeba przejść poprawnie proces autoryzacji, aby otrzymać wygenerowany unikalny adres strumienia wraz z hasłem.
Sam pomysł i realizacja tego procesu jest bardzo dobra i wymaga do prawidłowego przejścia procesu autoryzacji pliku wykonywalnego komunikatora Gadu-Gadu. Choć z czasem pojawienia się możliwości słuchania radia wprost ze strony www, metoda ta straciła swój potencjał poprzez wykorzystywanie tych samym danych1.
Działanie Gadu Radia w komunikatorze Gadu-Gadu opiera się na ukrytym procesie odtwarzacza Winamp, który w tle “odgrywa” strumień danego kanału radiowego. W przypadku strony internetowej, po zalogowaniu się wykorzystując swój numer sieci Gadu-Gadu, otrzymujemy wygenerowany adres URL strumienia.
Lista kanałów
Listę kanałów zawierającą informacje o dostępnych kanałach tematycznych radia oraz o namiarach na serwery można pobrać spod poniższego adresu, gdzie nazwa pliku składa się z daty ostatniej aktualizacji listy:
http://static.gaduradio.pl/stations/2008070201.xml
Jest to plik XML o prostej strukturze:
<?xml version="1.0" encoding="windows-1250"?>
<list xmlns="http://www.gaduradio.pl/schema/gr-im-channel-list"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.gaduradio.pl/schema/gr-im-channel-list
http://www.gaduradio.pl/schema/gr-im-channel-list.xsd">
<default chname="2">
<server ip="gr-lb-2.gaduradio.pl" port="80" authport="443"></server>
<server ip="gr-lb-1.gaduradio.pl" port="80" authport="443"></server>
</default>
<channel description="Orange Music" chname="31">
<server ip="gr-lb-2.gaduradio.pl" port="80" authport="443"></server>
<server ip="gr-lb-1.gaduradio.pl" port="80" authport="443"></server>
</channel>
.
.
.
<channel description="RADIO MUZANGO" chname="9">
<server ip="gr-lb-2.gaduradio.pl" port="80" authport="443"></server>
<server ip="gr-lb-1.gaduradio.pl" port="80" authport="443"></server>
</channel>
<version>2008070201</version>
</list>
Mam nadzieję, że jego omawianie nie jest konieczne, każdy z analizą powinien sobie bez problemu poradzić.
Plik z sygnaturą do listy kanałów znajduje się pod podobnym adresem co sama lista tylko z innym rozszerzeniem:
http://static.gaduradio.pl/stations/2008070201.sign
Niestety jego przeznaczenie nie jest znane.
Proces autoryzacji
Ogólny schemat jest prosty. Logujemy się na serwer Gadu Radia przy użyciu naszego konta w sieci Gadu-Gadu i pobieramy dane potrzebne do wyliczenia hasha, czyli wygenerowaną dynamicznie pozycję w pliku wykonywalnym (gg.exe
) komunikatora Gadu-Gadu, z której mamy wygenerować hash. Otrzymany hash odsyłamy do serwera, który w odpowiedzi prześle nam adres strumienia i tymczasowe hasło ważne tylko jedną sesję z serwerem strumieniowym.
Cała wymiana danych w procesie autoryzacji odbywa się za pomocą szyfrowanych połączeń HTTPS.
Otrzymywane odpowiedzi od serwera są porcjami danych zapisanymi w postaci rekordu CSV, gdzie jako znak separatora wykorzystano średnik. Wartość pierwszego pola określa rodzaj odpowiedzi.
W całym etapie autoryzacji występują dwa główne rodzaje, są to odpowiedzi potwierdzające poprawne wykonanie zapytania i zawierające niezbędne dane, o które proszono w zapytaniu - wartość pola wynosi 1
oraz odpowiedzi oznajmujące wystąpienie błędu wraz z odpowiednim komunikatem jego dotyczącym - wartość pola wynosi 0
.
Oprócz tego na różnych etapach autoryzacji można spotkać jeszcze inne, ale o tym wspominam w miejscu występowania.
Logowanie
Aby zalogować się na serwer i otrzymać dane niezbędne do wyliczenia hasha należy na jeden z serwerów dostępnych na liście z kanałami wysłać odpowiednie zapytanie GET:
/auth.gg?u=123456&p=password&c=33&v=7.7.0.3725&s=2008070201&w=5.2.4.703&r=0
Parametry u
i p
to dane do konta GG. Pole c
jest identyfikatorem kanału muzycznego jaki chcemy odtworzyć (w tym przypadku “Gadu Radio Chillout”). Należy jeszcze podać wersję używanego komunikatora Gadu-Gadu z jakiego będzie generowany hash w parametrze v
, używaną wersję listy kanałów w s
oraz wersję Winampa - parametr w
. Znaczenie wartości parametru r
jest bliżej nieznane. Wszystkie parametry oprócz r
są wymagane.
Na przykład dla kanału “Gadu Radio Chillout” będzie to równoważne z pobraniem strony:
https://gr-lb-1.gaduradio.pl/auth.gg?u=123456&p=password&c=33&v=7.7.0.3725&s=2008070201&w=5.2.4.703&r=0
W zależności od danych przekazanych serwerowi w zapytaniu, otrzymamy odpowiednią wiadomość.
Gdy popełniono błąd, przekazano niepoprawne dane lub z jakiś innych powodów logowanie nie mogło dojść do skutku, otrzymamy pakiet z odpowiednim komunikatem błędu.
W przypadku podania błędnych informacji, otrzymamy jeden z kilku komunikatów:
0;1;Nie udało się zalogować przy pomocy podanego numeru i hasła.;
0;1;Żądany kanał nie istnieje.;
0;1;Podana wersja komunikatora jest błędna.;
0;1;Podana wersja Winampa jest błędna.;
W przypadku nie obsługiwanych wersji komunikatora lub Winampa:
0;1;Ściągnij najnowszą wersję komunikatora Gadu-Gadu i najnowszą wersję Winampa.;
Może się też zdarzyć, ze wszystkie serwery Gadu Radia są w tej chwili pełne, wtedy dostaniemy odpowiedni komunikat:
0;1;Wszystkie serwery Gadu Radia są pełne, spróbuj ponownie za chwilę;
W aktualnych wersjach ciężko już “spotkać” powyższy komunikat błędu. Ale za czasów beta testów i pierwszych chwil życia usługi był dosyć często widywany ;)
Innym rodzajem odpowiedzi na jaki można natrafić na tym etapie procesu autoryzacji jest przekierowanie. Odpowiedź taka zawiera w pierwszym polu wartość 2
, a jej struktura prezentuje się następująco:
2;frog5a.gaduradio.pl:443;GaduRadioNonRDSMessage;
Jak można zauważyć, w drugim polu zawarto adres serwera, z którym należy ponowić logowanie, a w trzecim opcjonalną wiadomość lub wartość GaduRadioNonRDSMessage
oznaczająca brak takowej.
Po adresie serwera (z pierwszych wersji usługi) można wywnioskować, że odpowiedź ta była tak, jak w przypadku przepełnienia serwerów, dosyć często widoczna w czasach młodości usługi, obecnie ciężko na nią trafić.
Gdy podano poprawne dane i udało się wreszcie zalogować to serwer przekaże informacje niezbędne do wygenerowania hasha, ale o tym w następnym punkcie.
Generowanie hasha
Gdy uda się poprawnie zalogować na serwer, dostaniemy potrzebne dane do dalszego procesu autoryzacji:
1;1;1;1;1;600;Trwa logowanie do GaduRadio...;
https://gr-grr-15.gaduradio.pl:443/auth.gg;
http://static.gaduradio.pl:80/stations/2008070201;;
Pierwsze cztery pola (nie licząc pierwszego pola, określającego rodzaj odpowiedzi) zawierają dane niezbędne do wygenerowania hasha. Przeznaczenie następnego pola jest nieznane, z obserwacji wynika, że zawsze znajduje się tam stała wartość równa 600
. Dalej znajduje się wiadomość tekstowa wyświetlana w panelu informacyjnym radia w komunikatorze Gadu-Gadu lub wartość GaduRadioNonRDSMessage
.
Kolejne pole zawiera adres serwera i skryptu, do którego trzeba odesłać wygenerowany hash. Zawartość następnego pola to adres pliku (bez rozszerzenia xml) zawierający aktualną listę kanałów. Pole to jest opcjonalne i gdy w zapytaniu służącym do logowania podano aktualną wersję listy kanałów, pole to pozostanie puste. Następne, ostatnie pole jest nieznane, z obserwacji wynika, że zawsze puste.
Sam algorytm generowania hasha jest bardzo prosty.
Dla ułatwienia, cztery pola z danymi potrzebnymi do wygenerowania hasha oznaczono kolejno jako pos1
, len1
, pos2
i len2
. Z pliku gg.exe
należy odczytać len1
bajtów poczynając od pozycji pos1
oraz len2
od pos2
. Odczytane fragmenty danych połączyć ze sobą, a całość jeszcze ze stringiem %_Martyna
(jakaś dedykacja?). Z tak otrzymanego ciągu danych za pomocą algorytmu MD5 generowany jest 128-bitowy skrót, który jest wynikowym hashem.
Tak, jak wspominałem na początku, od czasu możliwości słuchania Gadu Radia via www metoda ta straciła swój potencjał, dlatego, że dane do wyliczenia hasha są zawsze takie same, pozycje i długości wynoszą 1
. Zatem wyliczoną wartość hasha dla danej wersji komunikatora można umieścić na stałe w kodzie.
Wygenerowany hash należy odesłać do serwera (na adres otrzymany wyżej) poprzez zapytanie:
/auth.gg?u=123456&h=ea509f39d8b45bac63326036c14540d2&v=7.7.0.3725
Parametr u
zawiera numer konta GG, h
wygenerowany właśnie hash, a v
wersję klienta GG z jakiej wyliczono hash.
Gdy jakieś dane nie były prawidłowe serwer odpowie jednym z kilku komunikatów błędu:
0;1;Podany numer Gadu-Gadu jest błędny.;
0;1;Błąd autoryzacji do Gadu-Radio.;
W przeciwnym razie, gdy wszystko przebiegło pomyślnie, serwer odeśle między innymi adres strumienia kanału i tymczasowe hasło, dzięki któremu będzie można zalogować się na serwerze strumieniowym, ale o tym w następnym punkcie.
Odtwarzanie
Po poprawnym zalogowaniu i wygenerowaniu hasha, gdy wszystko pójdzie sprawnie i nie będzie żadnych niespodzianek, serwer powinien odpowiedzieć paczką danych podobną do tej:
1;gr-grr-13.gaduradio.pl:80/33;Z1Hd4jUxbE;Dodaj do kontaktow nr 431 i wejdz na www.mamma-mia.com.pl;;
W pierwszym polu (nie licząc pola zawierającego rodzaj odpowiedzi) znajduje się adres strumienia kanału, a w następnym tymczasowe hasło niezbędne do zalogowania się na serwerze strumieniowym. Dalej znajduje się opcjonalna wiadomość wyświetlana w panelu radia, a ostatnie puste pole standardowo nie jest znane.
Mając adres strumienia kanału, tymczasowe hasło oraz numer GG użyty do logowania i autoryzacji, można złożyć adres URL strumienia kanału radiowego, który ma taką postać:
http://123456:Z1Hd4jUxbE@gr-grr-13.gaduradio.pl:80/33
Teraz wystarczy połączyć się z tym adresem z dowolnego playera obsługującego strumieniowe przesyłanie mediów i można oddać się przyjemności słuchania Gadu Radia.
Uwagi
Nie wiem jak obecnie wygląda sytuacja, ale w czasach młodości usługi, serwer lubił na próbę logowania odpowiadać takim oto komunikatem błędu:
0;1;Błąd klient-serwer;
Prawdopodobnie działo się tak, dlatego, że serwer porównywał używane wersje Gadu-Gadu - tą jaką deklarowaliśmy przy pobieraniu informacji o serwerach Gadu-Gadu z huba przy każdym włączeniu komunikatora, z tą jakiej użyliśmy do logowania się w usłudze Gadu Radio.
Rozwiązaniem okazało się pobranie informacji o serwerze Gadu-Gadu z huba appmsg.gadu-gadu.pl
z dokładnie takim numerem wiadomości systemowej, jak w poniższym zapytaniu:
/appsvc/appmsg4.asp?fmnumber=123456&version=7%%2C+7%%2C+0%%2C+3725&fmt=2&lastmsg=2951&dlp=32
Dokładny opis powyższego zapytania można znaleźć w dokumentacji protokołu Gadu-Gadu.
Komentarze (1)
No, dobra robota. Inna sprawa, czy gra warta świeczki przy ogromnej ilości normalnych stacji internetowych…