<?xml version="1.0" encoding="UTF-8" ?>
<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns="http://purl.org/rss/1.0/">

<channel rdf:about="http://devloop.lyua.org/blog/index.php">
  <title>devloop :: blog</title>
  <description><![CDATA[Blog sur la sécurité informatique, Linux et le Web]]></description>
  <link>http://devloop.lyua.org/blog/index.php</link>
  <dc:language>fr</dc:language>
  <dc:creator></dc:creator>
  <dc:rights></dc:rights>
  <dc:date>2008-08-23T15:41:38+00:00</dc:date>
  <admin:generatorAgent rdf:resource="http://www.dotclear.net/" />
  
  <sy:updatePeriod>daily</sy:updatePeriod>
  <sy:updateFrequency>1</sy:updateFrequency>
  <sy:updateBase>2008-08-23T15:41:38+00:00</sy:updateBase>
  
  <items>
  <rdf:Seq>
    <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/08/23/529-google-streetview-a-orleans" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/08/20/528-anywherefm-python-cli-player" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/08/18/527-enregistrer-les-videos-de-m6replay-beta-sous-windows-cest-possible" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/08/17/526-lire-directement-la-musique-de-anywherefm-ca-marche-presque" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/08/16/525-ecoutez-votre-musique-aleatoirement-pour-pas-un-rond-ou-presque-en-mode-console" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/08/07/524-dissection-de-anywherefm" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/08/03/523-jai-teste-le-live-cd-de-f-secure" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/08/02/522-convertir-des-nombres-en-ligne-de-commande" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/07/29/521-m6replay-beta-et-linux" />
  <rdf:li rdf:resource="http://devloop.lyua.org/blog/index.php?2008/07/19/520-un-air-de-ressemblance" />
  </rdf:Seq>
  </items>
</channel>

<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/08/23/529-google-streetview-a-orleans">
  <title>Google Street View à Orléans ?</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/08/23/529-google-streetview-a-orleans</link>
  <dc:date>2008-08-23T15:41:38+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Cyber et Sciences</dc:subject>
  <description>Il y a quelques jours, alors que je marchais dans la rue, j'ai été dépassé par une voiture avec un dispositif étrange placé sur le toit. Une bloc carré sur une espèce de trépied.
J'ai assez...</description>
  <content:encoded><![CDATA[ Il y a quelques jours, alors que je marchais dans la rue, j'ai été dépassé par une voiture avec un dispositif étrange placé sur le toit. Une bloc carré sur une espèce de trépied.<br />
J'ai assez rapidement pensé aux voitures <q>Street View</q> qui se chargent de prendre des photos à intégrer dans <em>Google Maps</em>. Bien que le dispositif ne ressemblait pas exactement à <a href="http://www.webcarnews.com/ressources/articles_dir/article_id2728/google-car-paris.jpg" hreflang="fr" target="_blank">certaines photos trouvées sur Internet</a>, je vois difficilement ce que ça pourrait être d'autre...<br />
<br />
Dans ma mémoire, cela ressemblait plus à un trépied, avec des pieds en diagonale. La voiture utilisée avait un look bien européen, peut-être même une <em>Renault</em> ou une <em>Citroën</em>, berline, propablement 4 portes, couleur très fonçée mais pas noire. Elle roulait assez doucement sans doute pour éviter de balancer le dispositif.<br />
<br />
Après vérification aujourd'hui, il semble que <a href="http://www.pcinpact.com/actu/news/44581-google-street-view-tour-france.htm?vc=1" hreflang="fr" target="_blank">les voitures de <em>Google</em> circulent bien en France</a>
D'après <a href="http://www.zorgloob.com/2008/05/google-street-view-paris.asp" hreflang="fr" target="_blank">des commentaires sur Zorgloob</a>, d'autres personnes auraient croisé ces voitures un peu partout en France, et notamment sur <em>Orléans</em> à la mi-mai et la semaine dernière... comme quoi ce n'était pas une hallucination :p <br />
<br />
Dans tous les cas j'ai vérifié sur <em>Google Maps</em> et aucune photo n'est présente pour le moment pour le lieu où j'ai croisé la famuse voiture :p <br />
Ca pourrait aussi être une société concurrente ou un petit malin qui a décidé de reprendre le principe... rien n'est sûr.]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/08/20/528-anywherefm-python-cli-player">
  <title>Anywhere.FM Python CLI Player</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/08/20/528-anywherefm-python-cli-player</link>
  <dc:date>2008-08-20T22:46:58+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Coding</dc:subject>
  <description>C'est après pas mal de recherches et de tests de code que je suis finalement parvenu à développer en Python un lecteur de ma musique présente sur le site Anywhere.FM :) 

Le dernier bug...</description>
  <content:encoded><![CDATA[ C'est après <a href="http://devloop.lyua.org/blog/index.php?2008/08/07/524-dissection-de-anywherefm" hreflang="fr">pas mal de recherches</a> et de <a href="http://devloop.lyua.org/blog/index.php?2008/08/17/526-lire-directement-la-musique-de-anywherefm-ca-marche-presque" hreflang="fr">tests de code</a> que je suis finalement parvenu à développer en Python un lecteur de ma musique présente sur le site <em>Anywhere.FM</em> :) <br />
<br />
Le dernier bug rencontré était, comme expliqué dans un précédent, le décodage de certaines chaines de caractères qui ne respectaient pas le format UTF-8. Le responsable était finalement le site lui-même ou plutôt les utilisateurs qui envoit des données au serveur à l'aide d'un navigateur utilisant un autre encodage.<br />
<br />
Ainsi dans mon cas, le décodage de mon profil échouait car dans les données retournées se trouvait entre autres le nom mal encodé <a href="http://fr.wikipedia.org/wiki/Ted_Gärdestad" hreflang="fr" target="_blank">Ted Gärdestad</a> correspondant à l'un des artistes les plus écoutés par une personne dans ma liste d'amis (la fonctione RPC <em>get_complete_profiles</em> du site renvoie beaucoup d'infos superflues :-| )<br />
<br />
Pour résoudre ce souci il fallait intervenir sur <a href="http://api.pyamf.org/pyamf.amf3-pysrc.html#Decoder.readString" target="_blank">la méthode readString de la classe Decoder</a> de PyAMF (module amf3).<br />
Comme je ne voulais pas et d'ailleurs ne pouvais pas modifier le code de PyAMF (installé sous forme de <q>egg</q> sur mon système), j'ai plutôt imaginé une technique de <q>Python API Hooking</q>.<br />
En fait il s'agit simplement de la redéfinition puis d'un écrasement d'une méthode d'une classe Python... mais avouez que dit comme ça, ça en jette beaucoup moins :p <br />
<br />
La vérification ajoutée à la méthode readString consistait à lever une exception si le passage en unicode échouait et dans ce cas, à remplacer les mauvais caractères par des underscore. Ce qui donnait :<br />

<pre>from pyamf.amf3 import Decoder
from string import maketrans

in_string=&quot;&quot;.join([chr(i) for i in range(126,256)])
out_string=&quot;_&quot;*130
trans=maketrans(in_string,out_string)

def my_readString(object, use_references=True):
  def readLength():
      x = object.readUnsignedInteger()

      return (x &gt;&gt; 1, x &amp; 1 == 0)

  length, is_reference = readLength()

  if use_references and is_reference:
      return object.context.getString(length)

  buf = object.stream.read(length)

  try:
    result = unicode(buf, &quot;utf8&quot;)
  except UnicodeDecodeError:
    buf=buf.translate(trans)
    result = unicode(buf, &quot;utf8&quot;)

  if len(result) != 0 and use_references:
      object.context.addString(result)

  return result

sav_readString=Decoder.readString
Decoder.readString=my_readString</pre>
<br />
L'opération de récupération et de correction de la liste de lecture <q>Entire Library</q> pouvant prendre un certain temps si la liste de lecture est importante, j'ai préféré diviser le programme en deux : le premier code récupère la liste de lecture et l'enregistre sous forme d'une liste Python dans un fichier ; le second est le lecteur qui charge la liste de lecture et va lire de façon aléatoire et unique un titre de la bibliothèque :) <br />
Au final on gagne largement en charge réseau et en temps d'accès par rapport à l'utilisation du site Internet et on n'a pas à subir les utilisations mémoire et processeur gourmandes du plugin Flash :p <br />
<br />
Vous avez donc <a href="http://devloop.lyua.org/releases/get_library.py">get_library.py</a> qui donne un résultat de ce style :<br />
<pre>Connection on the server...
Connexion successfull!
user_id = 5418
Hooking the PyAMF Decoder
Getting the Entire Library playlist...
Library dumped!</pre>
qui génère un fichier library.py utilisé par le lecteur <a href="http://devloop.lyua.org/releases/player.py">player.py</a> qui joue les flux musicaux et donne un affichage dans ce genre :<br />
<pre>Connecting on the server...
Connexion successfull
user_id = 5418
White America - Eminem ( The Eminem Show )
Troisième tour - Rapaces ( 2000 )
Les Poubelles du Coeur - Parabellum ( 1984-2004 )
Question de fun - Les Shériff ( La Saga Des Sheriff (disc 2) )
Alcohol - Dropkick Murphys ( Live On St. Patrick's Day )
Marilyn Moore - Sonic Youth ( Evol )
Come Back, Baby - Ramones ( The Chrysalis Years (disc 1) )
The Watcher - Dr. Dre ( 2001 )
...</pre>
La partie lecteur nécessite la présence de <em>mplayer</em> sur le système. Seul regret : on ne peut pas trop jouer sur l'interface de <em>mplayer</em> pour avoir quelque chose de moins verbeux et agréable... une simple barre de défilement de la lecture en cours (à l'instar de wget) m'aurait bien plu... mais c'est une autre histoire :)]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/08/18/527-enregistrer-les-videos-de-m6replay-beta-sous-windows-cest-possible">
  <title>Enregistrer les vidéos de M6Replay Béta sous Windows c'est possible</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/08/18/527-enregistrer-les-videos-de-m6replay-beta-sous-windows-cest-possible</link>
  <dc:date>2008-08-18T22:00:45+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Web</dc:subject>
  <description>J'étais désespéremment à la recherche d'une spécification qui aurait pû m'en apprendre sur le protocole RTMPE utilisé par la Béta de M6Replay, en particulier sur la couche de cryptage, quand...</description>
  <content:encoded><![CDATA[ J'étais désespéremment à la recherche d'une spécification qui aurait pû m'en apprendre sur <a href="http://devloop.lyua.org/blog/index.php?2008/07/29/521-m6replay-beta-et-linux" hreflang="fr">le protocole RTMPE utilisé par la Béta de M6Replay</a>, en particulier sur la couche de cryptage, quand je suis finalement tombé sur un blog parlant d'un logiciel qui avait réussi à <q>casser</q> cette protection.<br />
<br />
Ca m'a finalement amené à <a href="http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=15&amp;catid=578&amp;threadid=1331814" hreflang="en" target="_blank">cette discussion</a> sur le forum d'<em>Adobe</em>, puis <a href="http://www.applian.com/replay-media-catcher/" hreflang="en" target="_blank">au fameux logiciel</a> ainsi qu'à <a href="http://ask.slashdot.org/article.pl?sid=08/08/16/0230205" hreflang="en" target="_blank">un article sur le sujet sur Slashdot</a><br />
<br />
Après essai de <em>Replay Media Catcher</em>, il s'avère que effectivement ça fonctionne, entre autres sur <a href="http://www.m6replay.com/beta/" hreflang="fr" target="_blank">M6Replay Béta</a>.<br />
Bien sûr, aucune information n'est disponible sur le fonctionnement du logiciel mais il doit utiliser à priori une attaque de type <a href="http://fr.wikipedia.org/wiki/Attaque_de_l'homme_du_milieu" hreflang="fr" target="_blank">MITM</a>, se faisant passer auprès du plugin Flash comme le serveur de streaming avant de renvoyer le flux réencodé par ses soins vers le véritable serveur. Bref il doit agir comme un proxy.<br />
Le logiciel ne se sert pas de modules <em>Internet Explorer</em>, ni de la librairie pcap. Il n'y a donc pas, à la différence des logiciels concurrents, de sniffing. Le protocole RTMPE n'est donc pas <q>cassé</q>, ce sont juste les développeurs de <em>Replay Media Catcher</em> qui ont trouvé puis implémenté la bonne astuce :) <br />
<br />
Face à tout ça, <em>Adobe</em> a rajouté une clarification dans <a href="http://www.adobe.com/devnet/flashmediaserver/articles/protecting_video_fms.pdf" hreflang="en" target="_blank">un document sur son <em>Flash Media Server</em></a> (pdf).<br />
<br />
Et moi je n'ai trouvé aucune information intéressante sur le RTMPE... <a href="http://www.dailymotion.com/video/x3b4fo_on-nous-cache-tout-on-nous-dit-rien_news" hreflang="fr" target="_blank">la magie des logiciels propriétaires</a> :( <br />
<br />
<img src="http://xs230.xs.to/xs230/08341/m6replay_download352.png" alt="Télécharger les vidéos de M6Replay sous Windows avec Replay Media Catcher" /><br />
Ci-dessus, le fameux logiciel en action.]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/08/17/526-lire-directement-la-musique-de-anywherefm-ca-marche-presque">
  <title>Lire directement la musique de Anywhere.FM : ça marche (presque)</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/08/17/526-lire-directement-la-musique-de-anywherefm-ca-marche-presque</link>
  <dc:date>2008-08-17T20:19:09+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Coding</dc:subject>
  <description>Suite de ma précédente étude du fonctionnement de Anywhere.FM.

Je me suis lancé aujourd'hui dans la pratique en écrivant quelques lignes de code et les résultats sont pour le moins...</description>
  <content:encoded><![CDATA[ Suite de <a href="http://devloop.lyua.org/blog/index.php?2008/08/07/524-dissection-de-anywherefm" hreflang="fr">ma précédente étude du fonctionnement de Anywhere.FM</a>.<br />
<br />
Je me suis lancé aujourd'hui dans la <q>pratique</q> en écrivant quelques lignes de code et les résultats sont pour le moins encourageants :) <br />
Je me suis orienté naturellement vers les modules <em>urllib2</em> et <em>cookielib</em> de <em>Python</em> que j'avais utilisé pour <a href="http://wapiti.sourceforge.net/" hreflang="en" target="_blank">Wapiti</a>.<br />
<br />
Les premières étapes se sont réalisées sans problème (envoies de données par GET ou POST, utilisation d'une <q>boîte à cookies</q> :p )<br />
Pour la seconde étape j'avais le choix entre utiliser les capacitées de <a href="http://pyamf.org/" hreflang="en" target="_blank">PyAMF</a> à effectuer les requêtes mais en devant injecter mes entêtes HTTP ou rester sur l'utilisation du module <em>urllib2</em> et injecter les données encodées à l'aide de <em>PyAMF</em>.<br />
J'ai finalement opté pour la seconde méthode, même s'il m'a fallu un peu de temps pour comprendre quels arguments passer à quelles fonctions. Pour résumer j'utilise seulement les fonctionnalitées de création d'objet (plus propre) et d'encodeur/décodeur de <em>PyAMF</em> et toute la partie communication est réalisée par <em>urllib2</em>.<br />
<br />
J'ai d'abord implémenté les étapes que j'avais observé au complet puis j'ai ensuite commenté certaines étapes dont l'utilité était douteuse.<br />
Au final les réponses aux questions précédentes sont :<br />
<ul>
 <li>_unique_request_id_ est aléatoire. On peut même le définir nous même au début. Reprendre la même valeur à chaque nouvelle session ne semble pas poser de problème, même sur des intervalles de temps rapprochés. Je n'ai pas vérifié si on pouvait se passer de l'incrémentation d'une requête à une autre</li>
 <li>Les fameuses variabes __qca et __qcb définies par le biais du Javascript sur le serveur quantserve semblent totalement superflues. Ne pas les utiliser n'entrave en rien la communication avec Anywhere.FM. De toute évidence elles sont utilisées uniquement à des fins de tracking</li>
 <li>tracker_id n'a pas d'utilité, malgré qu'il soit explicitement défini (une requête est générée uniquement à cet effet). Il pourrait s'agir d'une fonctionnalitée que les administrateurs n'ont pas encore pû implémenté mais à venir ?!</li>
 <li>Certains arguments passés à <em>get_songs_for_user_playlists</em> restent un mystère, toutefois on n'a pas besoin d'en savoir plus pour accèder à la librairie complète d'un utilisateur</li>
</ul>
Le code que vous pourrez trouver ici : <a href="http://devloop.lyua.org/releases/PyAnywhereFM.py">PyAnywhereFM.py</a> et sur <a href="http://pastebin.com/f47f45685" hreflang="en" target="_blank">pastebin.com</a> n'est pas totalement fonctionnel.<br />
En effet si on parvient bien à ouvrir une session sur le site, à effectuer des requêtes AMF et obtenir les résultats, on ne parvientpas pour le moment à décoder les réponses AMF à cause d'erreurs de décodage UTF-8. A l'heure actuelle je ne saurais pas dire si le problème vient de <em>Anywhere.FM</em>, de <em>PyAMF</em> ou encore de <em>Python</em>...<br />
<br />
Il est tout de même possible d'obtenir un jeton valide pour accèder à un titre dont on connait par avance le <q>master_id</q> et le <q>song_ressource_id</q> (paramêtres qui sont fixes).<br />
Le code tente de se connecter avec les identifiants présents dans la source (à vous d'y insérer les votres) ou fonctionnera avec l'utilisateur par défaut (démo, id = 89 comme vu la dernière fois) si les identifiants sont invalides. Il va ensuite lire un titre dans ma librairie à l'aide de <em>mplayer</em>.<br />
<br />
Vous pouvez utiliser un sniffeur comme <a href="http://www.wireshark.org/" hreflang="en" target="_blank">Wireshark</a> pour comprendre ce qui se passe en fond lors de l'utilisation du script. Il faut noter toutefois que l'utilisateur <q>demo</q> a une librairie vide, c'est pour cela qu'il est possible de décommenter une ligne fixant le <em>user_id</em> à 46 (correspondant au compte <q>Free Music</q>)<br />
<br />
L'étape restante consiste donc à extraire les données des réponses AMF obtenues, ce qui ne devrait pas être trop difficile puisque le <q>master_id</q> et le <q>song_ressource_id</q> sont envoyés comme des chaines de caractères et non comme des entiers.<br />
Tout cela montre qu'il est assez aisé (le code fait 129 lignes une fois les commentaires et les lignes vides retirées) de télécharger de la musique sur <em>Anywhere.FM</em> et malgré qu'il n'y ait pas de système permettant de rechercher un titre en particulier, il serait possible de générer une base de données des titres disponibles en récupérant les profils puis les listes de lecture des utilisateurs du site. Evidemment ça prendrait du temps, mais ce serait toujours plus rapide que de fouiller par le biais de l'interface web du site :p]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/08/16/525-ecoutez-votre-musique-aleatoirement-pour-pas-un-rond-ou-presque-en-mode-console">
  <title>Ecoutez votre musique aléatoirement pour pas un rond (ou presque) en mode console</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/08/16/525-ecoutez-votre-musique-aleatoirement-pour-pas-un-rond-ou-presque-en-mode-console</link>
  <dc:date>2008-08-16T21:47:46+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Linux et logiciels libres</dc:subject>
  <description>L'astuce qui suit nécessite la présence d'un logiciel lisant le fichier qu'on lui passe en argument et quitte une fois arrivé à la fin du titre.
find /repertoire/vers/votre/musique/ -name...</description>
  <content:encoded><![CDATA[ L'astuce qui suit nécessite la présence d'un logiciel lisant le fichier qu'on lui passe en argument et quitte une fois arrivé à la fin du titre.<br /><br />
<pre>find /repertoire/vers/votre/musique/ -name &quot;*.mp3&quot; -print|sort -R|xargs -0 -d&quot;\n&quot; mplayer</pre>
La première commande fouille dans une arborescence les fichiers mp3 présents et génére une liste en affichant le chemon complet vers les fichiers.<br />
La seconde commande va réorganiser cette liste de façon aléatoire :) <br />
La dernière commande extrait chaque nom de fichier de la liste pour le passer en argument du lecteur audio (ici mplayer)]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/08/07/524-dissection-de-anywherefm">
  <title>Dissection de Anywhere.FM</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/08/07/524-dissection-de-anywherefm</link>
  <dc:date>2008-08-07T19:57:33+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Web</dc:subject>
  <description>Il y a presque un an maintenant j'avais testé Anywhere.FM, un site permettant d'uploader sa musique en ligne pour pouvoir ensuite la réécouter depuis n'importe quel poste connecté à Internet et...</description>
  <content:encoded><![CDATA[ Il y a presque un an maintenant <a href="http://devloop.lyua.org/blog/index.php?2007/08/15/462-jai-teste-anywherefm" hreflang="fr">j'avais testé Anywhere.FM</a>, un site permettant d'uploader sa musique en ligne pour pouvoir ensuite la réécouter depuis n'importe quel poste connecté à Internet et disposant du plugin <em>Flash</em> d'<em>Adobe</em>.<br />
C'est très pratique et agréable... quand cela fonctionne. Et malheureusement sous Linux, ça ne fonctionne pas souvent. Premièrement la fonction d'upload ne fonctionne pas sous Linux avec Flash9 (je n'ai pas testé avec la version béta 10), la faute à Adobe qui semble moins pressé quand il s'agit de systèmes libres. Deuxièmement la lecture des titres (et c'est quand même l'utilité principale du site) semble fonctionner uniquement quand ça lui chante... et de toute évidence depuis des mois le site a décidé qu'il ne voulait pas lire les musiques sous Linux. Ainsi l'animation Flash reste bloquée sur <q>Loading...</q>  mais ne charge rien du tout.<br />
<br />
Bref dans mon raz-le-bol général j'ai décidé d'analyser le fonctionnement du site et de voir s'il est possible de développer un petit quelque chose qui me permettrait de pouvoir lire ma musique en ligne directement sur les serveurs sans avoir à passer par l'interface pompeuse existante :p <br />
A l'heure actuelle il n'y a pas encore de code, seulement mon analyse qui dévoile la grosse partie du fonctionnement du site.<br />
<br />
<strong>Identification</strong><br />
Si vous rendez sur une des urls du site, vous serez redirigés automatiquement vers http://www.anywhere.fm/player/. Cette page est chargée dynamiquement et en fonction de la page que vous avez demandé en premier, différentes variables seront passées à l'animation Flash chargée dans le navigateur (par exemple pour indiquer qu'il faut aller chercher la librairie de tel utilisateur).<br />
Durant ce premier contact avec le site, un identifiant de session PHP (variable <em>PHPSESSID</em>) vous sera attribué et vous n'en changerez normalement pas même si vous fermez/ouvrez une session sur le site.<br />
Cette variable de session définie comme cookie est spécifique à l'hôte <em>www</em> du domaine <em>anywhere.fm</em> (d'autres hôtes entrent en jeu comme on le verra plus tard).<br />
<br />
<strong>Tracking</strong><br />
La page chargée fait appel à différents scripts JavaScript dont un qui a sans doute un rôle de tracking (analyse pour étude commerciale etc) mais à l'heure de ces lignes je ne le jurerais pas.<br />
Le script en question se situe à l'adresse <a href="http://edge.quantserve.com/quant.js">http://edge.quantserve.com/quant.js</a> et il déclare une variable nommée <q>dc</q> qui est générée aléatoirement par le serveur.<br />
La fonction principale nommée <em>quantserve()</em> récupère différentes informations sur la configuration de l'internaute et construit une url vers un <q>pixel traqueur</q> qui est ensuite chargée par le client pour envoyer les données au serveur <em>pixel.quantserve.com</em>.<br />
<br />

La partie qui nous intéresse dans ce script (mais qui est peut-être optionnelle) est la modification des cookies.<br />
La variable <em>dc</em> qui était définie se retrouve dans les cookies sous le nom <q>__qca</q>.<br />
Une autre variable, générée aléatoirement en JavaScript (code : <em>Math.round(Math.random()*2147483647)</em> ) est aussi ajoutée au cookie et se nomme <q>__qcb</q>.<br />
<br />
Contrairement à <em>PHPSESSID</em> qui est propre à <em>www</em>, <em>__qca</em> et <em>__qcb</em> sont propres à l'ensemble du domaine.<br />
<br />
<strong>Crossdomain</strong><br />
L'animation Flash étant chargée, elle a besoin de vérifier qu'elle a bien la permission de communiquer avec certains serveurs. Pour cela elle va demander pour chacun un fichier <a href="http://wiki.mediabox.fr/tutoriaux/flash/crossdomain.xml" hreflang="fr" target="_blank">crossdomain.xml</a> qui définie les règles d'accès.<br />
Parmis les serveurs on trouve <em>music</em>, <em>upload-XX</em> (XX étant un nombre multiple de 5) et <em>upload-full</em>.<br />
<br />
<strong>Authentification</strong><br />
L'animation ayant déterminée qu'elle pouvait dialoguer avec <em>musique.anywhere.fm</em>, elle effectue une requête GET sur la page /account/get_current_user?_unique_request_id_=XXXXXXXXXXXXXX.<br />
L'argument <em>_unique_request_id_</em> a pour valeur un nombre probablement aléatoire mais toujours très grand. Cet <q>identifiant unique de requête</q> est incrémenté à chaque communication avec le serveur <em>music</em>.<br />
<br />
Le serveur <em>music</em> donne ses réponses sous le format XML. En l'absence de la saisie de vos identifiants, les données renvoyées sont <a href="http://music.anywhere.fm/account/get_current_user">celle de l'utilisateur par défaut</a> (<em>user_id</em> = 89, <em>login</em> = demo, <em>fullname</em> = Lux)<br />
<br />
La page en profite pour définir trois nouvelles variables de cookie :<br />
<ul>
 <li><em>auth_token</em> et <em>auth_session_id</em> ont pour restriction l'hôte <em>music</em></li>
 <li><em>_HotPot_session_id</em> est défini sur tout le domaine <em>anywhere.fm</em></li>
</ul>
Ces trois variables sont typiques des variables de session : 32 caractères sous l'alphabet hexadécimal.<br />
Malgré leur nom différents, <em>auth_session_id</em> et <em>_HotPot_session_id</em> ont la même valeur.<br />
<br />
L'opération suivante est un POST à l'adresse /account/create_login_tracker?_unique_request_id_=XXXXXXXXXXXXXX.<br />
Les variables vues précédemment et concernant l'hôte <em>music</em> ou tout le domaine sont bien sûr renvoyés à nouveau au serveur.<br />
Les données passées dans le corps de la requêtes sont <em>session_id</em> (correspondant à <em>auth_session_id</em> de tout à l'heure) et <em>user_id</em> (correspondant à celui renvoyé par la requête précédente soit 89 ici).<br />
Cela renvoit une information très courte de la forme : <em>&lt;tracker_id&gt;XXXXXXXXXX&lt;/tracker_id&gt;</em><br />
<br />
<strong>Introduction à AMF</strong><br />
Débutent alors les communications <em>AMF</em> avec le serveur <em>www</em>. <a href="http://en.wikipedia.org/wiki/Action_Message_Format" hreflang="en" target="_blank">Action Message Format</a> est un format de données créé à l'origine par <em>Macromedia</em> puis conservé par <em>Adobe</em>.<br />
Il est utilisé principalement par Flash pour des communications <a href="http://en.wikipedia.org/wiki/Remote_Procedure_Call" hreflang="en" target="_blank">RPC</a>.<br />
L'avantage par rapport à un formatage XML sont son format binaire (on n'est pas resteint à des caractères imprimables) et son gain de place. Il utilise notemment un système de références qui permet de ne pas avoir à redéfinir des données déjà envoyées (pour le moment je n'ai pas étudié en détails ce sujet).<br />
On pourrait comparer ce format au <a href="http://devloop.lyua.org/blog/index.php?2007/08/26/464-utilisations-alternatives-du-protocole-bittorrent" hreflang="fr">bencodage de BitTorrent</a> mais en réalité il est bien plus complexe, voire carrément prise de tête (rien que <a href="http://osflash.org/documentation/amf3" hreflang="en" target="_blank">le codage d'entiers sur 29 bits donne un aperçu</a>)<br />
De plus deux versions existent : AMF0 et AMF3. Il peut possible d'intégrer des données AMF3 dans du AMF0 par le biais d'un type particulier (0x11)<br />
Les requêtes HTTP transportant des données AMF ont l'entête <q>Content-Type: application/x-amf</q><br />
<br />
Ce format n'étant pas le sujet de l'article, je n'en dirais pas plus pour le moment.<br />
<br />
<strong>Connexion</strong><br />
Passons pour l'instant sur les échanges <em>RPC</em> qui ont été faits, et rentrons nos identifiants de connexion sur le site.<br />
Cela génère une requête POST sur /account/login?_unique_request_id_=XXXXXXXXXXXXXX sur le serveur <em>music</em>. L'identifiant de requête a (ne l'oublions pas) été incrémenté à plusieurs reprises et cela ne changera pas.<br />
Les données envoyées sont :<br />
<ul>
 <li>dans le header Cookie : <em>__qca</em>, <em>__qcb</em>, <em>auth_token</em>, <em>auth_session_id</em> et <em>_HotPot_session_id</em></li>
 <li>dans le body : <q>login</q> et <q>password</q></li>
</ul>
<em>auth_session_id</em> et <em>_HotPot_session_id</em> ont toujours la même valeur.<br />
La réponse du serveur nous informe d'une nouvelle valeur pour <em>auth_token</em> (qui définie donc notre session utilisateur sur le serveur <em>music</em>)<br />
Sur le serveur <em>www</em>, aucun changement n'est à prendre en compte, les données du cookies n'ont pas changées.<br />
<br />
Les deux requêtes effectuées avant connexion sont répétées sauf que <em>get_current_user</em> renverra notre <em>user_id</em> et <em>create_login_tracker</em> renverra une nouvelle valeur.<br />
<br />
<strong>RPC et Flex</strong><br />
Les échanges RPC sont effectués uniquement avec le serveur <em>www</em> et à destination de la page
<blockquote>/amfphp/gateway.php?_unique_request_id_=XXXXXXXXXXXXXX</blockquote>
Les requêtes RPC sont toujours groupées par deux et ont le même <em>_unique_request_id_</em>. <em>Anywhere.FM</em> utilise les librairies <a href="http://fr.wikipedia.org/wiki/Adobe_Flex" hreflang="fr" target="_blank">Flex</a> dans ses échanges.<br />
On trouve ainsi deux types de messages :<br />
<ul>
 <li>flex.messaging.messages.CommandMessage : permet de faire un <q>ping</q> du serveur. C'est toujours la première requête du groupe</li>
 <li>flex.messaging.messages.RemotingMessage : permet d'appeler une fonction RPC sur le serveur. C'est toujours la seconde requête</li>
</ul>
Ces fonctions <em>Flex</em> se basent toujours sur les mêmes arguments.<br />
Concernant les fonctions RPC, l'argument <em>source</em> sera toujours fixé à <q>BlazingFast.DBQueries</q>. L'argument <em>operation</em> contient le nom de la fonction à appeler sur le serveur et <em>body</em> est un tableau contenant les arguments à y passer.<br />
<br />
<strong>Fonctions</strong><br />
Le premier argument de chacune des fonctions existante correspont au <em>auth_session_id</em>, permettant ainsi au serveur de vérifier les permissions d'accès aux données.<br />
<br />
La première fonction qui nous intéresse est <em>get_complete_profiles</em>. Elle prend deux argument : le premier est (bien entendu) l'identifiant de session et le second est un tableau contenant une liste d'identifiants utilisateur.<br />
Le résultat retourné est un tableau contenant des informations diverses sur les utilisateurs correspondant, notemment les liste de titres dont ils disposent.<br />
Trois données importantes permettent de définir une playlist : <em>playlist_type</em>, <em>playlist_id</em> et <em>playlist_name</em><br />
Le type d'une playlist aura la valeur 200 s'il s'agit de la collection entière de l'utilisateur et 300 s'il s'agit d'une librairie personnalisée.<br />
<br />
La fonction <em>get_songs_for_user_playlists</em> pourrait se définir de cette façon :<br />
get_songs_for_user_playlists(session_id, user_id, bool, [playlist_id], [playlist_type], ['0','0'...])<br />
Le rôle du booléen en troisième argument m'échappe pour le moment ainsi que le tableau de chaines de caractères définie à '0'.<br />
Cette fonction retourne un tableau qui peut être imposant définissant chaque titre d'une liste de lecture. En dehors des données <q>classiques</q> (name, artist, album), on trouve les données <q>master_id</q> et <q>song_ressource_id</q> qui permettent de récupérer une adresse valide pour un titre donné.<br />
<br />
C'est la fonction <em>get_song_url</em> qui nous donne le sésame. On pourrait la déclarer de cette façon :<br />
get_song_url(session_id, user_id, master_id, song_ressource_id)<br />
Elle retourne une chaine de caractères correspondant à une url HTTP vers le fichier MP3 :) <br />
Cette url dispose d'une clé d'accès ainsi qu'un temps de validation. Par conséquent il ne doit pas être possible d'utiliser deux fois la même url.<br />
<br />
<strong>Conlusion</strong><br />
Il reste de nombreux points à éclaircir qui doivent pouvoir être déterminés par expérimentation comme :<br />
<ul>
 <li>_unique_request_id_ est-il généré aléatoirement au début ?</li>
 <li>Les variables définies par quantserve() ont-elle une utilité autre que le tracking ?</li>
 <li>Quelle utilité a la valeur tracker_id</li>
 <li>A quoi sert le booléen et le tableau de chaines passé à get_songs_for_user_playlists ?</li>
</ul>
<br />
<strong>Netographie</strong><br />
<a href="http://osflash.org/documentation/" hreflang="en" target="_blank">Open Source Flash documentation</a><br />
<a href="http://pyamf.org/" hreflang="en" target="_blank">PyAMF</a> (les codes sources m'ont bien aidé)<br />
<a href="http://www.charlesproxy.com/" hreflang="en" target="_blank">Charles Web Debugging Proxy</a> : Un proxy qui comprend l'AMF :) Malheureusement en shareware :( <br />
<br />
<strong>Ping Flex</strong><br />
Pour terminer un petit exemple de code utilisant l'API PyAMF qui réalisé un ping en Flex (merci aux développeurs de l'API pour leur aide ;-) ) :<br />

<pre>import pyamf
from pyamf.remoting import client
from pyamf.flex import messaging
from pyamf import remoting

gw = client.RemotingService('http://127.0.0.1/',pyamf.AMF0,pyamf.ClientTypes.Flash9)
message = messaging.CommandMessage(body={},
    timestamp=0,
    destination='',
    clientId=None,
    headers={'DSId': u'nil'},
    timeToLive=0,
    messageId='7478D81C-65B4-EA4B-B52E-4689507A7241',
    operation=5,correlationId='',
    messageRefType='flex.messaging.messages.CommandMessage')
gw.addRequest('null', message)
gw.execute()</pre>]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/08/03/523-jai-teste-le-live-cd-de-f-secure">
  <title>J'ai testé le Live-CD de F-Secure</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/08/03/523-jai-teste-le-live-cd-de-f-secure</link>
  <dc:date>2008-08-03T21:56:49+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Sécurité Informatique</dc:subject>
  <description>Un petit billet pour vous dire que j'ai testé F-Secure Rescue CD 3.00.
Comme vous le devinez, c'est un live-cd permettant de chercher des virus sur les systèmes installés sur la machine....</description>
  <content:encoded><![CDATA[ Un petit billet pour vous dire que j'ai testé <a href="http://www.f-secure.com/linux-weblog/2008/06/19/f-secure-rescue-cd-300-released/" hreflang="en" target="_blank">F-Secure Rescue CD 3.00</a>.<br />
Comme vous le devinez, c'est un live-cd permettant de chercher des virus sur les systèmes installés sur la machine. L'avantage de pouvoir scanner un système <q>off</q> (qui n'est pas démarré) est que l'on peut détecter des malwares qui se rendent invisibles quand le système est en marche (rootkits...)<br />
L'inconvénient est évidemment que l'on s'en remet uniquement à l'analyse par signature (qui comme tout n'est pas parfaite).<br />
<br />
J'ai d'abord essayé de le faire fonctionner sur un PC avec clavier USB. Après lancement du kernel Linux utilisé par le CD, on arrive sur un écran qui nous invite à appuyer sur une touche pour continuer. Sans quoi après 15 secondes, le système installé va démarrer.<br />
Malheureusement le kernel utilisé ne doit pas supporter les claviers USB puisque aucune touche ne semblait répondre alors que juste avant j'ai pû aller dans le BIOS avec le même clavier pour rajouter le lecteur CD dans les périphériques de boot :( <br />
J'ai laissé un message à F-Secure par leur site, en espérant que ce soit corrigé.<br />
<br />
Sur un autre système (sans clavier USB), le lancement s'est fait sans problème. L'interface est simple et épurée, il n'y a pas besoin d'être un habitué de Linux ou de la ligne de commande pour l'utiliser.<br />
Une tentative de téléchargement de la dernière base antivirale est faite. Chez moi ça n'a pas fonctionné (à la fin su scan ça affichait mai 2008) mais difficile de déterminer pour qu'elles raisons (DHCP ? DNS ?)<br />
<br />
Ensuite vient le scan en lui-même. L'antivirus vérifie le MBR ainsi que les différentes partitions. Les drivers NTFS-3G sont utilisés de cette façon l'antivirus peut agir sur le système de fichier de Windows. Je ne jugerais pas de la qualité de l'AV en lui-même, ce n'est pas le but de l'article. Les quelques virus qui étaient intentionnelement présents sur le disque ont été détectés, rien d'autre n'a été trouvé comme quoi le système devait être propre.<br />
L'antivirus renomme les fichiers infectés en y ajoutant l'extension <q>.virus</q>. Avant de lancer le scan, un message nous prévient que le renommage des fichiers systèmes peut poser problème. Peut-être qu'il manque d'informations sur ce point pour les non-informaticiens qui pourraient se retrouver avec un système propre mais inutilisable.<br />
<br />
Au final c'est très pratique, efficace et bon à avoir sous la main en cas de pépin même si quelques points mériteraient d'être améliorés.]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/08/02/522-convertir-des-nombres-en-ligne-de-commande">
  <title>Convertir des nombres en ligne de commande</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/08/02/522-convertir-des-nombres-en-ligne-de-commande</link>
  <dc:date>2008-08-02T17:39:27+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Linux et logiciels libres</dc:subject>
  <description>Tout bidouilleur qui se respecte a forcément à portée de main (ou de quelques clics de souris) une table ascii et un logiciel pour convertir des chiffres d'une base à une autre (binaire, décimal,...</description>
  <content:encoded><![CDATA[ Tout <q>bidouilleur</q> qui se respecte a forcément à portée de main (ou de quelques clics de souris) une table ascii et un logiciel pour convertir des chiffres d'une base à une autre (binaire, décimal, hexadécimal, octal).<br />
En ce qui me concerne, pour la table ascii j'ai la même qui traine sur mon bureau depuis environ 8 ans :p Par contre le problème se pose pour la conversion des chiffres. J'ai plutôt tendance à utiliser la calculatrice de <em>KDE3</em> (KCalc) mais ça m'oblige à passer par le menu <em>KDE</em>, choisir <q>Applications</q>, <q>Utilitaires</q>, <q>Calculatrice</q>... ce n'est pas très rapide surtout que si on ferme la calculatrice on est bon pour répéter le même cheminement la première fois :( <br />
<br />
Bref ce serait tellement plus rapide d'avoir un outil de conversion de nombres en ligne de commande :) <br />
Sous Linux on a bien <q>bc</q> qui permet de réaliser des conversions en utilisant les commandes <q>ibase</q> et <q>obase</q>.<br />
<pre>&gt; <strong>bc
obase=2
ibase=16
DEADC0DE</strong>
11011110101011011100000011011110</pre>
Ca marche bien seulement là encore on a plein de choses à taper, c'est interactif : on ne peut pas passer les arguments en ligne de commande et utiliser un echo+pipe ça ne me dit trop rien...<br />
<br />
Après quelques recherches peu concluantes, j'ai finalement trouvé un petit outil sympathique sur <em>SourceForge</em> nommé <a href="http://sourceforge.net/projects/numcv/" hreflang="en" target="_blank">Number Converter (numcv)</a>.<br />
<br />
Pour le compiler on utilisera la commande <q>gcc -o numcv numcv.c -lm</q>.<br />
La commande prend trois arguments. Le premier est la base d'origine du nombre qui tient sur un seul caractère : 'o' pour octal, 'd' pour décimal, 'h' pour hexadécimal et 'b' pour binaire.<br />
Le second argument est le nombre à convertir et enfin le dernier argument est la base de sortie pour la conversion (les même caractères que précédemment).<br />
<br />
Ce qui donne par exemple :<br />
<pre>&gt; <strong>numcv d 31337 x</strong>
0x7a69
&gt; <strong>numcv x 29a d</strong>
666
&gt; <strong>numcv o 56 b</strong>
101110</pre>
On peut en plus spécifier la base 'a' qui nous permet de connaître la valeur d'un caractère ascii :<br />
<pre>&gt; <strong>numcv a A x</strong>
0x41</pre>
Le seul inconvénient est que l'on ne peut convertir qu'un nombre/caractère à la fois. Et aussi une fonction <em>usage()</em> avec une option <em>-h</em> ne serait pas du luxe :p <br />
<br />
Au final un outil sympathique en ligne de commande et qui s'avère vite indispensable :)]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/07/29/521-m6replay-beta-et-linux">
  <title>M6Replay Béta et Linux</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/07/29/521-m6replay-beta-et-linux</link>
  <dc:date>2008-07-29T20:39:19+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Linux et logiciels libres</dc:subject>
  <description>Vous êtes peut-être au courant de l'existence d'une version béta de M6Replay qui permet aux utilisateurs de Linux et Mac de profiter des vidéos du site de M6.

Je m'étais déjà penché il y a...</description>
  <content:encoded><![CDATA[ Vous êtes peut-être au courant de l'existence d'une <a href="http://blogm6replay.m6blog.fr/archive/2008/07/28/m6-replay-beta-compatible-mac-et-linux.html" hreflang="fr" target="_blank">version béta de M6Replay</a> qui permet aux utilisateurs de Linux et Mac de profiter des vidéos du site de <em>M6</em>.<br />
<br />
Je m'étais déjà penché il y a quelques temps sur la version initiale (pour le moment toujours la version officielle) histoire de voir si il était possible de bricoler une <q>zapette</q> comme celle <a href="http://devloop.lyua.org/blog/index.php?2007/10/02/470-la-zapette-de-canal" hreflang="fr">pour les émissions en clair de Canal+</a>.<br />
Après avoir pas mal fouillé, et trouvé assez facilement les urls des flux, il s'avérait que le protocole utilisait était du <q>RTSP-over-HTTP</q> (ou du moins quelque chose dans ces eaux là :D ), qu'on pouvait normalement le lire en bidouillant les options de VLC ou en passant un simple <q>mms://</q> au lieu du protocole dit officiel.<br />
On final on avait bien de l'image et du son mais pas vraiment ce qu'on désirait. J'ai quand même cru discerner durant un dixième de seconde une paire d'yeux au milieu d'un artistique nuage jaune fluo et de taches oranges... à moins que ce soit l'effet du hazard :p <br />
En fait il semblerait qu'un codec propiétaire (DRM-powered) soit utilisé en plus, rendant impossible la lecture sur les systèmes libres :( <br />
<br />
Avec la version béta les vidéos sont bien lisibles sous Linux, mais M6 s'est visiblement cresé la tête pour trouver une solution tout aussi imbuvable.<br />
Ca fonctionne donc avec le lecteur <em>Flash</em> (qui rappelons le est propriétaire)... mais pas autre chose.<br />
<br />
On a bien <a href="http://www.m6replay.fr/beta/jsp/getxml.jsp" target="_blank">un flux XML</a> dans lequel on retrouve des urls du style<br />
<em>mp4:production/live/DIFF_28072008/H264_UN_DINER_PRESQ__UN_DINER_PRESQ__280720080615__LIVE.mp4</em><br />
et en observant le traffic réseau on sait que le flux vidéo est lu depuis le serveur <em>fcds98.lon.llnw.net</em> (le nom de machine n'est probablement pas fixe) mais à part ça difficile de retrouver un lien direct pour y pointer son lecteur multimédia préféré.<br />
<br />
Après recherches le flux vidéo utiliserait le <a href="http://rtmpy.org/wiki/RTMP" hreflang="en" target="_blank">protocole RTMP</a> (<em>Real Time Messaging Protocol</em>), un protocole (bien évidemment) propriétaire développé par <em>Macromédia</em> (avant rachat par <em>Adobe</em>).<br />
Il existe <a href="http://www.orbitdownloader.com/" hreflang="en" target="_blank">différents</a> <a href="http://www.wmrecorder.com/" hreflang="en" target="_blank">outils</a> <a href="http://www.flvrecorder.com/" hreflang="fr" target="_blank">closed-source</a> pour capturer les vidéos des flux RTMP, la majorité se basant sur le même principe que <a href="http://home.twmi.rr.com/compn/rtmp.cpp" target="_blank">cette source C++</a> à savoir utiliser la librairie pcap et surveiller tout ce qui communique avec le port TCP 1935.<br />
<br />
Le protocole RTMP a aussi été analysé et est utilisé par le projet <q>Open Source Flash</q> par le biais du serveur <a href="http://osflash.org/red5" hreflang="en" target="_blank">Red5</a>.<br />
Comble du bonheur, <a href="http://forum.videolan.org/viewtopic.php?f=2&amp;t=48286" hreflang="en" target="_blank">les versions béta de VLC</a> (&gt;= 0.9.*) supportent le RTMP :) <br />
<br />
Petit problème : <em>M6Replay</em> utilise à priori le <em>RTMPE</em> (<q>RTMPE is a version of RTMP which is an 128-bit encrypted protocol</q>), ce qui fait que ces outils se montrent inefficaces.<br />
<br />
Bref pour le moment seulement le lecteur <em>Flash</em> peut lire ces vidéos sous Linux. Il reste à trouver les adresses exactes des flux et attendre que le <em>RTMPE</em> soit supporté par un logiciel libre pour pouvoir en profiter <q>pleinement</q>.]]></content:encoded>
</item>
<item rdf:about="http://devloop.lyua.org/blog/index.php?2008/07/19/520-un-air-de-ressemblance">
  <title>Un air de ressemblance</title>
  <link>http://devloop.lyua.org/blog/index.php?2008/07/19/520-un-air-de-ressemblance</link>
  <dc:date>2008-07-19T16:59:49+00:00</dc:date>
  <dc:language>fr</dc:language>
  <dc:creator>devloop</dc:creator>
  <dc:subject>Divers</dc:subject>
  <description>C'est complétement par hazard que je suis tombé sur une image où je retrouvais le logo de présent blog. A l'origine j'avais trouvé le smiley seul sur un autre site avant de le réutiliser, mais...</description>
  <content:encoded><![CDATA[ C'est complétement par hazard que je suis tombé sur une image où je retrouvais le logo de présent blog. A l'origine j'avais trouvé le smiley <q>seul</q> sur un autre site avant de le réutiliser, mais sur cette nouvelle image il était accompagné...<br />
Après un bon temps passé sur <em>Google</em> et <em>Yahoo!</em>, j'ai finalement retrouvé <a href="http://dragonkahn.deviantart.com/art/Today-597304" hreflang="en">l'image et l'auteur original</a>. Il s'agissait d'un sympathique wallpaper :) <br /><br />
J'en profite pour faire un petit screenshot de mon environnement actuel (ça faisait longtemps) : <em>KDE4</em> avec le thème <em>Aya</em> et un Widget qui m'affiche les strips de <em>User-Friendly</em>.<br />

<a href="http://img501.imageshack.us/img501/9827/screenshotni2.png"><img src="http://img501.imageshack.us/img501/9827/screenshotni2.th.png" alt="devloop screenshot" /></a>]]></content:encoded>
</item>

</rdf:RDF>
