Skip navigation.

devloop :: blog

Blog sur la sécurité informatique, la programmation, Linux et le Web

Posts tagged with "http"

Anywhere.FM Python CLI Player

, , , ...

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 :smile:

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.

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é Ted Gärdestad correspondant à l'un des artistes les plus écoutés par une personne dans ma liste d'amis (la fonctione RPC get_complete_profiles du site renvoie beaucoup d'infos superflues :-| )

Pour résoudre ce souci il fallait intervenir sur la méthode readString de la classe Decoder de PyAMF (module amf3).
Comme je ne voulais pas et d'ailleurs ne pouvais pas modifier le code de PyAMF (installé sous forme de "egg" sur mon système), j'ai plutôt imaginé une technique de "Python API Hooking".
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:

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 :
from pyamf.amf3 import Decoder
from string import maketrans

in_string="".join([chr(i) for i in range(126,256)])
out_string="_"*130
trans=maketrans(in_string,out_string)

def my_readString(object, use_references=True):
  def readLength():
      x = object.readUnsignedInteger()

      return (x >> 1, x & 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, "utf8")
  except UnicodeDecodeError:
    buf=buf.translate(trans)
    result = unicode(buf, "utf8")

  if len(result) != 0 and use_references:
      object.context.addString(result)

  return result

sav_readString=Decoder.readString
Decoder.readString=my_readString

L'opération de récupération et de correction de la liste de lecture "Entire Library" 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 :smile:
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:

Vous avez donc get_library.py qui donne un résultat de ce style :
Connection on the server...
Connexion successfull!
user_id = 5418
Hooking the PyAMF Decoder
Getting the Entire Library playlist...
Library dumped!

qui génère un fichier library.py utilisé par le lecteur player.py qui joue les flux musicaux et donne un affichage dans ce genre :
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 )
...

La partie lecteur nécessite la présence de mplayer sur le système. Seul regret : on ne peut pas trop jouer sur l'interface de mplayer 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 :smile:

Lire directement la musique de Anywhere.FM : ça marche (presque)

, , , ...

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 encourageants :smile:
Je me suis orienté naturellement vers les modules urllib2 et cookielib de Python que j'avais utilisé pour Wapiti.

Les premières étapes se sont réalisées sans problème (envoies de données par GET ou POST, utilisation d'une "boîte à cookies" p: )
Pour la seconde étape j'avais le choix entre utiliser les capacitées de PyAMF à effectuer les requêtes mais en devant injecter mes entêtes HTTP ou rester sur l'utilisation du module urllib2 et injecter les données encodées à l'aide de PyAMF.
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 PyAMF et toute la partie communication est réalisée par urllib2.

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.
Au final les réponses aux questions précédentes sont :
  • _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
  • 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
  • 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 ?!
  • Certains arguments passés à get_songs_for_user_playlists restent un mystère, toutefois on n'a pas besoin d'en savoir plus pour accèder à la librairie complète d'un utilisateur

Le code que vous pourrez trouver ici : PyAnywhereFM.py et sur pastebin.com n'est pas totalement fonctionnel.
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 Anywhere.FM, de PyAMF ou encore de Python...

Il est tout de même possible d'obtenir un jeton valide pour accèder à un titre dont on connait par avance le "master_id" et le "song_ressource_id" (paramêtres qui sont fixes).
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 mplayer.

Vous pouvez utiliser un sniffeur comme Wireshark pour comprendre ce qui se passe en fond lors de l'utilisation du script. Il faut noter toutefois que l'utilisateur "demo" a une librairie vide, c'est pour cela qu'il est possible de décommenter une ligne fixant le user_id à 46 (correspondant au compte "Free Music")

L'étape restante consiste donc à extraire les données des réponses AMF obtenues, ce qui ne devrait pas être trop difficile puisque le "master_id" et le "song_ressource_id" sont envoyés comme des chaines de caractères et non comme des entiers.
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 Anywhere.FM 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:

Dissection de Anywhere.FM

, , , ...

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 disposant du plugin Flash d'Adobe.
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 "Loading..." mais ne charge rien du tout.

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:
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.

Identification
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).
Durant ce premier contact avec le site, un identifiant de session PHP (variable PHPSESSID) vous sera attribué et vous n'en changerez normalement pas même si vous fermez/ouvrez une session sur le site.
Cette variable de session définie comme cookie est spécifique à l'hôte www du domaine anywhere.fm (d'autres hôtes entrent en jeu comme on le verra plus tard).

Tracking
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.
Le script en question se situe à l'adresse http://edge.quantserve.com/quant.js et il déclare une variable nommée "dc" qui est générée aléatoirement par le serveur.
La fonction principale nommée quantserve() récupère différentes informations sur la configuration de l'internaute et construit une url vers un "pixel traqueur" qui est ensuite chargée par le client pour envoyer les données au serveur pixel.quantserve.com.

La partie qui nous intéresse dans ce script (mais qui est peut-être optionnelle) est la modification des cookies.
La variable dc qui était définie se retrouve dans les cookies sous le nom "__qca".
Une autre variable, générée aléatoirement en JavaScript (code : Math.round(Math.random()*2147483647) ) est aussi ajoutée au cookie et se nomme "__qcb".

Contrairement à PHPSESSID qui est propre à www, __qca et __qcb sont propres à l'ensemble du domaine.

Crossdomain
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 crossdomain.xml qui définie les règles d'accès.
Parmis les serveurs on trouve music, upload-XX (XX étant un nombre multiple de 5) et upload-full.

Authentification
L'animation ayant déterminée qu'elle pouvait dialoguer avec music.anywhere.fm, elle effectue une requête GET sur la page /account/get_current_user?_unique_request_id_=XXXXXXXXXXXXXX.
L'argument _unique_request_id_ a pour valeur un nombre probablement aléatoire mais toujours très grand. Cet "identifiant unique de requête" est incrémenté à chaque communication avec le serveur music.

Le serveur music donne ses réponses sous le format XML. En l'absence de la saisie de vos identifiants, les données renvoyées sont celles de l'utilisateur par défaut (user_id = 89, login = demo, fullname = Lux)

La page en profite pour définir trois nouvelles variables de cookie :
  • auth_token et auth_session_id ont pour restriction l'hôte music
  • _HotPot_session_id est défini sur tout le domaine anywhere.fm

Ces trois variables sont typiques des variables de session : 32 caractères sous l'alphabet hexadécimal.
Malgré leur nom différents, auth_session_id et _HotPot_session_id ont la même valeur.

L'opération suivante est un POST à l'adresse /account/create_login_tracker?_unique_request_id_=XXXXXXXXXXXXXX.
Les variables vues précédemment et concernant l'hôte music ou tout le domaine sont bien sûr renvoyés à nouveau au serveur.
Les données passées dans le corps de la requêtes sont session_id (correspondant à auth_session_id de tout à l'heure) et user_id (correspondant à celui renvoyé par la requête précédente soit 89 ici).
Cela renvoit une information très courte de la forme : <tracker_id>XXXXXXXXXX</tracker_id>

Introduction à AMF
Débutent alors les communications AMF avec le serveur www. Action Message Format est un format de données créé à l'origine par Macromedia puis conservé par Adobe.
Il est utilisé principalement par Flash pour des communications RPC.
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).
On pourrait comparer ce format au bencodage de BitTorrent mais en réalité il est bien plus complexe, voire carrément prise de tête (rien que le codage d'entiers sur 29 bits donne un aperçu)
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)
Les requêtes HTTP transportant des données AMF ont l'entête "Content-Type: application/x-amf"

Ce format n'étant pas le sujet de l'article, je n'en dirais pas plus pour le moment.

Connexion
Passons pour l'instant sur les échanges RPC qui ont été faits, et rentrons nos identifiants de connexion sur le site.
Cela génère une requête POST sur /account/login?_unique_request_id_=XXXXXXXXXXXXXX sur le serveur music. L'identifiant de requête a (ne l'oublions pas) été incrémenté à plusieurs reprises et cela ne changera pas.
Les données envoyées sont :
  • dans le header Cookie : __qca, __qcb, auth_token, auth_session_id et _HotPot_session_id
  • dans le body : "login" et "password"

auth_session_id et _HotPot_session_id ont toujours la même valeur.
La réponse du serveur nous informe d'une nouvelle valeur pour auth_token (qui définie donc notre session utilisateur sur le serveur music)
Sur le serveur www, aucun changement n'est à prendre en compte, les données du cookies n'ont pas changées.

Les deux requêtes effectuées avant connexion sont répétées sauf que get_current_user renverra notre user_id et create_login_tracker renverra une nouvelle valeur.

RPC et Flex
Les échanges RPC sont effectués uniquement avec le serveur www et à destination de la page
/amfphp/gateway.php?_unique_request_id_=XXXXXXXXXXXXXX
Les requêtes RPC sont toujours groupées par deux et ont le même _unique_request_id_. Anywhere.FM utilise les librairies Flex dans ses échanges.
On trouve ainsi deux types de messages :
  • flex.messaging.messages.CommandMessage : permet de faire un "ping" du serveur. C'est toujours la première requête du groupe
  • flex.messaging.messages.RemotingMessage : permet d'appeler une fonction RPC sur le serveur. C'est toujours la seconde requête

Ces fonctions Flex se basent toujours sur les mêmes arguments.
Concernant les fonctions RPC, l'argument source sera toujours fixé à "BlazingFast.DBQueries". L'argument operation contient le nom de la fonction à appeler sur le serveur et body est un tableau contenant les arguments à y passer.

Fonctions
Le premier argument de chacune des fonctions existante correspont au auth_session_id, permettant ainsi au serveur de vérifier les permissions d'accès aux données.

La première fonction qui nous intéresse est get_complete_profiles. 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.
Le résultat retourné est un tableau contenant des informations diverses sur les utilisateurs correspondant, notemment les liste de titres dont ils disposent.
Trois données importantes permettent de définir une playlist : playlist_type, playlist_id et playlist_name.
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.

La fonction get_songs_for_user_playlists pourrait se définir de cette façon :
get_songs_for_user_playlists(session_id, user_id, bool, [playlist_id], [playlist_type], ['0','0'...])
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'.
Cette fonction retourne un tableau qui peut être imposant définissant chaque titre d'une liste de lecture. En dehors des données "classiques" (name, artist, album), on trouve les données "master_id" et "song_ressource_id" qui permettent de récupérer une adresse valide pour un titre donné.

C'est la fonction get_song_url qui nous donne le sésame. On pourrait la déclarer de cette façon :
get_song_url(session_id, user_id, master_id, song_ressource_id)
Elle retourne une chaine de caractères correspondant à une url HTTP vers le fichier MP3 :smile:
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.

Conlusion
Il reste de nombreux points à éclaircir qui doivent pouvoir être déterminés par expérimentation comme :
  • _unique_request_id_ est-il généré aléatoirement au début ?
  • Les variables définies par quantserve() ont-elle une utilité autre que le tracking ?
  • Quelle utilité a la valeur tracker_id ?
  • A quoi sert le booléen et le tableau de chaines passé à get_songs_for_user_playlists ?

Netographie
Open Source Flash documentation
PyAMF (les codes sources m'ont bien aidé)
Charles Web Debugging Proxy : Un proxy qui comprend l'AMF :smile: Malheureusement en shareware :frown:

Ping Flex
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 ;-) ) :
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()

MISC on Steroids

, , , ...

Hier, après une grasse mat' bien méritée, j'ai découvert avec grand plaisir dans ma boîte aux lettres le numéro 30 du magazine de sécurité informatique MISC.

Certes ils nous ont habitués à leur sens de l'humour et à leurs références geek mais visiblement avec ce numéro on est passé au niveau supérieur.
L'édito donne déjà le ton avec l'histoire d'un petit groupe d'aventuriers apprentis (un paladin, un clerc, un voleur et un mage) qui doivent faire face à un dragon ; le tout avec un clin d'oeil aux indétrônables Monty Python.

S'ensuit un dossier sur le les botnets avec des noms de chapitres farfelus. J'apprécie particulièrement le "Un 0day mon prince viendra". On relèvera aussi le "Botherders de tous les pays, unissez-vous !" suivi plus loin par un "Une solution : la virtualisation ?"

Mais s'il fallait décerner une palme, aucun doute qu'elle reviendrait à l'article sur Skype titré "Une totale liberté de pensée cosmique vers un nouvel age réminiscent", référence a un film culte dans lequel on trouve des autruches qui donnent des coups de boule, des suédois extraterrestre bodybuildés à lunettes noires, un chien qui fume de l'herbe, un transexuel en cours de correction hormonale, une bande de nanas top-canon et plus encore.

Je n'ai lu que 4 articles jusqu'à présent mais ce numéro 30 m'a l'air particulièrement bon. Vous trouverez le sommaire ici.

Au passage, toutes mes félicitations à une personne qui se reconnaîtra, dommage qu'on ne puisse pas te lire plus souvent :wink:

Sinon j'entends de plus en plus parler de botnets basés sur HTTP au lieu du protocole IRC (pour le contrôle des zombies) et j'aimarais bien avoir plus d'infos sur le sujet donc si quelqu'un a un document, des références voire des sources traitant de leur fonctionnement je suis preneur :smile:

Spyce

, , , ...

Spyce est un framework web basé sur le langage Python. Il conviendra à tous ceux qui cherchent une solution puissante et très légère pour mettre en place serveur et applications web.
Avec Spyce on code directement en Python. Bien que quelques directives propres à Spyce soient disponibles, on peut inclure directement du code Python dans le code des pages, tout comme si on codait en PHP :smile:
Spyce intègre différents modules qui permettent de communiquer avec les bases de données, créer des espaces utilisateurs privés (sessions, cookies), gérer les redirections... bref tout ce dont on peut avoir besoin (sinon la puissance de Python est à notre disposition)

L'installation est on ne peut plus simple : on dézippe, on se place dans le répertoire décompressé puis on lance le serveur :
./spyceCmd.py -l

Le serveur écoute par défaut sur le port 8000 et les pages proposées sont celles du site officiel (documentation, exemples...)
Les pages doivent avoir une extension .spy ou .spi pour être interprétées.

Ma première page n'a pas été un "Hello World!" mais un 99 bottles of beer :
[[ for i in range(99,1,-1): { ]]
<p>[[=i]] bottles of beer on the wall, [[=i]] bottles of beer.<br />
Take one down and pass it around, [[=i-1]] bottles of beer on the wall.</p>
[[ } ]]
<p>1 bottle of beer on the wall, 1 bottle of beer.<br />
Take one down and pass it around, no more bottles of beer on the wall.</p>
<p>No more bottles of beer on the wall, no more bottles of beer.<br />
Go to the store and buy some more, 99 bottles of beer on the wall.</p>

J'ai aussi fait un script qui permet de lister les pages d'un site en appelant lswww :
[[ import spyce ]]
[[!
def scan(self,api):
  import lswww
  myls=lswww.lswww(request['url'])
  myls.verbosity(0)
  myls.go()
  for url in myls.getLinks():
    print url+"<br />"
]]
<f:form>
  Url : <f:text name='url' /><br />
  <f:submit handler='self.scan' value="Launch lswww" />
</f:form>
Powered by Spyce [[= spyce.__version__ ]]


Tout ça c'est sympathique, seulement les applications Spyce-Powered (forums, blogs...) ne doivent pas courir les rues. Heureusement on n'est pas obligé d'utiliser Spyce comme serveur puisqu'il peut être lancé comme un CGI ou en utilisant mod_python (voir la doc d'installation)

I think I'm paranoid

, , , ...

Non je ne suis pas (encore (complètement)) parano... mais j'y travaille
Et il faut dire aussi que l'on m'aide bien en ce sens...

C'était il y a tout juste quelques minutes sur ce blog : en consultant mes statistiques bbclone je me retrouve face à la ligne suivante.

J'ai de temps en temps des visiteurs qui bossent dans l'armée ou un ministère mais en général il s'agit d'ips françaises... j'ai donc décidé de mener ma petite enquête :sherlock:
Je lance donc ce fameux Google et obtient le résultat suivant :

Fort G. Meade, Fort G. Meade... ça me dis quelque chose... en plus je sais que c'est récent, j'ai dû lire un truc sur le sujet il n'y a pas longtemps...
Une seule solution pour combler ce trou de mémoire : une nouvelle recherche sur Google puis un clic sur un lien pointant vers Wikipedia...
Fort George G. Meade
En regardant la photo illustrant la page j'ai un gros doute... est-ce que c'est possible que...

In the 1950s, the post became headquarters of the National Security Agency (NSA).


*cough*cough*
Bon c'est bien ce que je pensais... voyons un peu ce qu'ils sont venus chercher

Argh ! Et dire que mes coordonées sont sur mon site ! Les types en noir vont débarquer chez-moi en voyageant dans un de leurs hélicoptères noir ! C'est sûr, ils ont pas appréçié que je parle de leur petites affaires, ou alors ils ont lu le mail que j'avais envoyé pour savoir s'ils intercepteraient la communication et c'est cela qui leur a donné l'envie d'en savoir plus sur moi... ou alors c'est juste un bot du réseau Echelon...

C'est décidé : demain je mets Shirley et ma collection de cds audio dans ma caisse et je taille la route pour la Chine, me faire pirate à la solde du gouvernement. Sinon je trouverais bien un taff pour la mafia russe.

Houla ! Calme-toi ! Regarde de plus près...

Quoi ? La NSA passerait par un proxy appartenant à un abonné de chez Free.fr ? :eyes:
Ca sent l'utilisation d'un proxy local tout ça... avec trifouillage des headers HTTP au vol p:

En tout cas c'est bien pensé, je dois avouer qu'il y a de l'idée et que l'adresse IP est très très bien choisie :up:
Enfin si le petit rigolo sous Debian avec son install d'Apache toute neuve voulait bien se donner la peine de laisser un petit message ici ce serais l'occasion de rigoler un peu :D
Et encore merci pour cette occasion de faire un billet :wink:

Derniers logiciels testés

, , , ...

Je vais vous parler brièvement des derniers logiciels que j'ai installé sous Linux.

J'ai voulu essayer KTouch, un logiciel de dactylographie, pour apprendre à tapper avec tous mes doigts... Après plusieurs essais j'ai toujours pas compris comment ça marche... On a une image d'un clavier avec des touches de différentes couleurs et une phrase à tapper et retapper le plus vite possible. A part ça je n'ai rien vu qui explique clairement comment placer ses doigts sur le clavier... je cherche toujours...

KID3 est un éditeur de tag pour les fichiers MP3. Il supporte le format ID3v1 et le ID3v2. Très simple d'utilisation et très pratique... surtout que XMMS ne semble gérer qu'un seul format. Il n'y a que l'interface qui n'est pas très belle mais le logiciel marche très bien.

Gqcam est un des logiciels que j'ai testé pour ma webcam. Le seul défaut est que le logiciel a tendance à oublier les préférences que l'on a fixé lors de la dernière utilisation... Donc à chaque lancement il faut activer la correction RBG -> GBR (sinon les images sont bleues) et désactiver l'autoréglage de la luminosité (qui tourne en boucle).
Le logiciel permet de faire des captures au format jpg ou png. L'interface est ultra-simple à utiliser... c'est pour l'instant le logiciel que j'utilise le plus avec la webcam.

Camorama est un autre logiciel pour webcam... Chez moi la définition est plus petite qu'avec Gqcam mais Camorama permet d'appliquer différents effets à l'image tel que le mode noir et blanc, le mode négatif, un flou ou encore les algorithmes de Laplace, Sobel, Wacky... On peut assez facilement se faire une image plus ou moins dans un style matrix ou terminator p:
Mais la petite taille des images générées gache un peu :frown:

Corkscrew est un logiciel de tunneling HTTP. Il utilise la méthode CONNECT du protocole. Pour ceux qui n'y connaissent rien le tunneling est une encapsulation d'un flux de données dans un protocole... à ne pas confondre avec les canaux cachés où on injecte les données dans le protocole lui-même.
Corkscrew prend quatre arguments : ip du proxy, port du proxy, ip de la machine destination et port de la machine destination. Le logiciel marche sous la forme d'un netcat, c'est à dire que ce que l'on tappe dans la console est envoyé sur le réseau... Ca limite donc l'utilisation du logiciel... on aurait préféré une redirection des communications de façon transparente et surtout permettant d'utiliser Corkscrew avec les logiciels standards (clients FTP, IRC etc)
D'ailleurs je vais peut-être coder une petite tool de tunneling HTTP en Python un de ces jours :wink:

Pour terminer j'ai testé deux programmes : Code2HTML et Source-highlight. Ils permettent, à partir d'un fichier source, de générer une belle page HTML avec le code en couleur (coloration syntaxique). Bref deux programmes qui se rendent indispendables si on souhaite publier une étude de code etc. Les deux outils supportent un nombre de langages impréssionnant (allez voir sur leurs sites respectifs) ainsi qu'une plétore d'options pour personnaliser la page HTML générée.

Fin de la transmission :cool:
January 2009
S M T W T F S
December 2008February 2009
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31