LastFmReverseEngineering
Introduction
Audioscrobbler (maintenant connu sous le nom de Last.FM) avait une radio web très puissante et très utile. Il suffisait de cliquer sur "play" et ça envoyait un .pls à votre player mp3 qui jouait les tounes qui avait rapport à votre profil. Très intéressant, car ça donne des tounes intéressantes. Enfin... Last.fm ont toujours ce service, mais malheureusement plus au travers d'un player web qui donne un .pls. Non, maintnenant ils offrent leur propre player MP3, ce qui est un peu stupide, car bien des gens ont leur propre player et n'ont pas envie d'une autre solution. D'autant plus que le player de Last.FM joue seulement les stations de Last.FM et non d'autres MP3s.
Donc, comment passer à côté de ça? Et bien, un peu de reverse engineering, bien sûr!
L'étude
J'ai téléchargé le code source du player et j'ai regardé le code source. On y trouve:
http->setHost( Settings::instance()->debug() ? "wsdev.audioscrobbler.com" : "ws.audioscrobbler.com" );
connect( http, SIGNAL( responseHeaderReceived( QHttpResponseHeader ) ), this, SLOT( handshakeHeaderReceived( QHttpResponseHeader ) ) );
connect( http, SIGNAL( requestFinished( int, bool ) ), this, SLOT( handshakeFinished( int, bool ) ) );
http->get( QString( "/radio/handshake.php?version=%1&platform=%2&username=%3&passwordmd5=%4&debug=%5&partner=%6" )
.arg( "1.0.4" )
.arg( platform )
.arg( QString( QUrl( username ).toEncoded() ) )
.arg( password )
.arg( Settings::instance()->debug() ? "1" : "0" )
.arg( "" ) );
La solution
On peut donc deviner que le player fait une requête HTTP du genre:
GET /radio/handshake.php?version=%1&platform=%2&username=%3&passwordmd5=%4&debug=%5&partner=%6
Host: ws.audioscrobbler.com
Où:
- %1: version ("1.0.4")
- %2: platform ("linux", "win32" ou "mac")
- %3: username
- %4: md5-encoded password
- %5: debug (0 or 1)
- %6: partner ("")
En passant, pour générer le mot de passe sous Linux, il faut utiliser:
echo -n "password" | md5sum
car sinon le newline entre dans le md5sum et le change.
Si nous avons construit l'url correctement, ça nous donne:
session=<id_de_session_du_genre_md5>
stream_url=http://streamer1.audioscrobbler.com/last.mp3?Session=<id_de_session_du_genre_md5>
subscriber=0
framehack=0
base_url=ws.audioscrobbler.com
base_path=/radio
Vous n'avez qu'à charger le stream_url
dans votre player mp3, vous allez streamer directement des mp3s de votre station préférée!!
Le script
#! /bin/sh
# this script will output a url that can be loaded in any player
# it needs the username as an argument, and asks for the password
# through stdin
# it could be called like this:
#
# $ xmms `$0 anarcat`
# WARNING: this is insecure as it echoes the typed password through a
# pipeline and is therefore subject to discovery using a timely ps(1)
# call
# default parameters
VERSION=1.0.4
PLATFORM=linux
USERNAME=$1
DEBUG=0
# read the password, not echoing to terminal
stty -echo
echo -n Password:\ >&2
read PASSWORD
stty echo
# cleanup and encrypt the password
md5=`echo -n $PASSWORD | md5sum - | cut -f 1 -d " "`
# do the request take the result back, cut in pieces to get the url
curl "http://ws.audioscrobbler.com//radio/handshake.php?version=$VERSION&platform=$PLATFORM&username=$USERNAME&passwordmd5=$md5&debug=$DEBUG&partner="2>/dev/null | grep stream_url | cut -f 2- -d '='