Возникла необходимость управлять сип-адаптером Linksys PAP2. Суть в том, что по заданому алгоритму надо снимать и включать регистрацию. Было выяснено, что для этого достаточно заснифать запрос при настроенном адаптере и менять 0 и 1 (выкл. и вкл. регистрации) в нужном месте. В беспарольном режиме проблем не возникает - делается обычным TIdHTTP и работает на ура. Но так как в сети я работаю через свич, а не через роутер, то без пароля оставлять адаптер не хочется. Было также выяснено, что авторизаций проходит по методу Digest authentication. В итоге пробовал и через TidHTTP, но, чтобы не возиться с иключениями (всё равно не вышло), перешёл на TIdTCPClient. Набросал такой код: Получем данные для авторизации:
| Код | idtcpclient1.Connect; idtcpclient1.WriteStrings(hdr); idtcpclient1.WriteLn; idtcpclient1.WriteLn(s); reply := idtcpclient1.ReadString(300);
|
Тут хэдер имеет вид:
| Код | hdr.add('POST /admin/linksys.pbp HTTP/1.1'); hdr.add('User-Agent: Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00'); hdr.add('Host: 10.0.47.142'); hdr.add('Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1'); hdr.add('Accept-Language: uk-UA,uk;q=0.9,en;q=0.8'); hdr.add('Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1'); hdr.add('Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0'); hdr.add('Authorization: Digest username="admin", realm="pap admin", uri="/admin/linksys.pbp", algorithm=MD5, nonce="00000144a70725a51b9918d4610cd7d32c3e2421",'+ ' cnonce="ORTaG58O11iRQ/pUYJOe1v8spMPQLgzUd6aA5iCo+kJ=", opaque="000be99524aa14a5ed3d533a5588067dd64bf5cf", qop=auth, nc=00000001, response="8ab99b6cd9960e129cc2a98258a1f8c0"'); hdr.add('Referer: http://10.0.47.142/admin/basic'); hdr.add('Connection: Keep-Alive, TE'); hdr.add('TE: deflate, gzip, chunked, identity, trailers'); hdr.add('Content-Length: 1762'); hdr.add('Content-Type: application/x-www-form-urlencoded');
|
Далее пробуем посчитать значение response:
| Код | i := pos('realm="', reply); i := i + 7; realm := midstr(reply, i, posex('"', reply, i) - i); i := pos('nonce="', reply); i := i + 7; nonce := midstr(reply, i, posex('"', reply, i) - i); i := pos('qop="', reply); i := i + 5; qop := midstr(reply, i, posex('"', reply, i) - i); i := pos('opaque="', reply); i := i + 5; opaque := midstr(reply, i, posex('"', reply, i) - i); HA1 := MD5ToString(MD5String('admin:'+realm+':MY_PASSWORD')); HA2 := MD5ToString(MD5String('POST:/admin/linksys.pbp')); response := MD5ToString(MD5String(HA1+':'+nonce+':00000001:'+cnonce+':'+qop+':'+HA2));
|
Формируем заголовок с данными для авторизации:
| Код | hdr.add('POST /admin/linksys.pbp HTTP/1.1'); hdr.add('User-Agent: Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00'); hdr.add('Host: 10.0.47.142'); hdr.add('Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1'); hdr.add('Accept-Language: uk-UA,uk;q=0.9,en;q=0.8'); hdr.add('Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1'); hdr.add('Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0'); hdr.add('Authorization: Digest username="admin", realm="pap admin", uri="/admin/linksys.pbp", algorithm=MD5, nonce="'+nonce+'",'+ ' cnonce="U+cXNW8vlBV/nCnH21fcA087STOD49mjG+h/Fhgi2QN=", opaque="'+opaque+'", qop=auth, nc=00000002, response="'+response+'"'); hdr.add('Referer: http://10.0.47.142/admin/basic'); hdr.add('Connection: Keep-Alive, TE'); // hdr[11] := 'Content-Length: 1762'; hdr.add('TE: deflate, gzip, chunked, identity, trailers'); hdr.add('Content-Length: 1762'); hdr.add('Content-Type: application/x-www-form-urlencoded');
|
И отсылаем его аналогично запросу. Отвечает Connection closed gracefully. Где я ошибся? |