No dobra trochę się poświęciłem i wgrałem nowszy soft do swojego modemu dzięki czemu mogłem zgłębić trochę tajniki HilinkAPI dla nowszych fw (jak się zdaje dotyczy oprogramowania powyżej wersji 22.29x.xx.xxx). Postaram się całość zamieścić w głównym temacie przy okazji wprowadzić parę poprawek i dopisać parę nowych API wprowadzonych jak się zdaje wraz z WebUI 17, ale poniżej zamieszczę wzmiankę o głównej zmianie, która blokowała korzystanie z API HiLinka.
W nowym fw zmienia się kompletnie sposób weryfikacji komend API. Przedtem był to
token pobierany z adresu
/api/webserver/token. Obecnie jest to weryfikacja sesji.
Cezary z
eko.one.pl, dla potrzeb 3ginfo, odpytując HiLinki z nowym fw robi myk w postaci
pobrania ciasteczka ze strony głównej
192.168.8.1/html/home.html i następnie z komendami API przekazuje ciasteczko. Ciasteczko zawiera zmienną
SessionID. Teoretycznie jest ok komendy działają i wszyscy sa szczęśliwi. A może jednak nie do końca, bo po pierwsze wymaga pobrania ciasteczka ze strony html, a po drugie jak spróbujemy pobrać listę sms'ów dostaniemy błąd sesji 125002 (powinien co prawda wystąpić błąd 125003, ale mniejsza o to)
Podgląd jak to robi stronka sms modemu HiLink wskaże, że przekazywany jest token, który pobierany jest z... nagłówka meta generowanego dynamicznie tej strony html (w zasadzie występują 2 nagłówki meta o nazwie
csrf_token, ale uprzedzając pytania nie wiem czemu są dwa)
No dobra pytanie skąd bierze się SessionID i token sesji? Wygląda na to, że jest to zaszyte gdzieś w fw, bo przypadek sprawił, że znalazłem adres
/api/webserver/SesTokInfo (próbowałem hexedytorem podejrzeć plik update'u

). Wywołując to API na nowym fw dostajemy 2 zmienne.
- Informacje o identyfikatorze sesji - SesInfo która zawiera właśnie zmienną SessionID oraz
- Informację o tokenie sesji - TokInfo, który zawiera token.
Teraz trochę praktyki.
- Pobranie informacji o sesji:
Kod: Zaznacz cały
curl -X GET http://192.168.8.1/api/webserver/SesTokInfo
da nam odpowieź:
Kod: Zaznacz cały
<?xml version="1.0" encoding="UTF-8"?>
<response>
<SesInfo>SessionID=gsU8x5ODj9CdzmYTG2pA5AUWnnQtHj0nbi4JuSGKfrK+siCdrFM1NBQu8Au6VpXgEm+8VtstHPIT55l74Z1UHmXcz7JBjQO2xMOYv+1PQkh8+BLIy6D6rOF34CB5R9s7</SesInfo>
<TokInfo>c1w6RrxlvkKA0TzGnZmS9/uTCbHTtN9f</TokInfo>
</response>
- Większość API (przynajmniej z części informacyjnej - GET) obsługuje się przekazując zmienną SesInfo jako ciasteczko. Można to zrobić na dwa sposoby:
- po bożemu jak sama nazwa wskazuje czyli parametrem odpowiedzialnym za ciasteczko:
Kod: Zaznacz cały
curl -X GET http://192.168.8.1/api/device/signal --cookie "SessionID=gsU8x5ODj9CdzmYTG2pA5AUWnnQtHj0nbi4JuSGKfrK+siCdrFM1NBQu8Au6VpXgEm+8VtstHPIT55l74Z1UHmXcz7JBjQO2xMOYv+1PQkh8+BLIy6D6rOF34CB5R9s7" -H "Content-Type: text/xml"
- lub przekazując jako nagłówek "Cookie":
Kod: Zaznacz cały
curl -X GET http://192.168.8.1/api/device/signal -H "Cookie: SessionID=gsU8x5ODj9CdzmYTG2pA5AUWnnQtHj0nbi4JuSGKfrK+siCdrFM1NBQu8Au6VpXgEm+8VtstHPIT55l74Z1UHmXcz7JBjQO2xMOYv+1PQkh8+BLIy6D6rOF34CB5R9s7" -H "Content-Type: text/xml"
- Niektóre API (część konfiguracyjna - POST) może dodatkowo wymagać podania tokena. Tak więc np. pobranie listy sms będzie wyglądało następująco (wersja z przekazaniem SessionID jako nagłówka):
Kod: Zaznacz cały
curl -X POST -d "<request><PageIndex>1</PageIndex><ReadCount>20</ReadCount><BoxType>1</BoxType><SortType>0</SortType><Ascending>0</Ascending><UnreadPreferred>0</UnreadPreferred></request>" http://192.168.8.1/api/sms/sms-list -H "Cookie: SessionID=gsU8x5ODj9CdzmYTG2pA5AUWnnQtHj0nbi4JuSGKfrK+siCdrFM1NBQu8Au6VpXgEm+8VtstHPIT55l74Z1UHmXcz7JBjQO2xMOYv+1PQkh8+BLIy6D6rOF34CB5R9s7" -H "__RequestVerificationToken: c1w6RrxlvkKA0TzGnZmS9/uTCbHTtN9f" -H "Content-Type: text/xml"
I jeszcze jedna uwaga... Token sesji i identyfikator sesji jest często zmieniany. Nie pamiętam w tej chwili konkretnych liczb, ale trzeba mieć to na uwadze. Stare API tokena /api/webserver/token zwykle podawało ten sam numer przez dość długi czas. Nowe API /api/webserver/SesTokInfo za każdym razem podaje inny wynik. Pewnie wynika to z szyfrowania, ale zbyt długo zastanawiając się nad komendami API dość szybko można odkryć, że dostaniemy w wyniku komendy błąd sesji 125002 (przeterminowany SessionID). Dlatego automatyzując działanie skryptów trzeba uwzględnić powyższe uwagi. Np plik wsadowy dla Windowsa można rozwiązać w ten sposób (wymaga narzędzi: curl, grep, cut):
Kod: Zaznacz cały
@ECHO OFF
rem przypisanie zmiennej modIPAdr adresu IP modemu
@SET modIPAdr=192.168.8.1
rem pobranie tokena oraz ID sesji i zapisanie do zmiennych
@curl -s -X GET http://%modIPAdr%/api/webserver/SesTokInfo > tmp.tmp
type tmp.tmp | grep SesInfo | cut -d ^> -f2 | cut -d ^< -f1 > tmp1.tmp
type tmp.tmp | grep TokInfo | cut -d ^> -f2 | cut -d ^< -f1 > tmp2.tmp
@del /A /F tmp.tmp
@SET /p sid= < tmp1.tmp
@del /A /F tmp1.tmp
@SET sid=Cookie: %sid%
@SET /p tok= < tmp2.tmp
@del /A /F tmp2.tmp
@SET tok=__RequestVerificationToken: %tok%
rem pobranie listy sms'ów
@curl -X POST -d "<request><PageIndex>1</PageIndex><ReadCount>20</ReadCount><BoxType>1</BoxType><SortType>0</SortType><Ascending>0</Ascending><UnreadPreferred>0</UnreadPreferred></request>" http://%modIPAdr%/api/sms/sms-list -H "%sid%" -H "%tok%" -H "Content-Type: text/xml"
@pause