Mar 28 2011

TOR et HADOPI

Juste pour faire un petit point autour de la HADOPI et plus précisément de la position de la HADOPI envers les proxy, et plus spécifiquement de la distribution des proxy comme le fait TOR.

La HADOPI n'empêche en rien l'utilisation de proxy, en somme l'utilisation de TOR ou d'un quelque autre proxy pour se connecter à internet (et donc utiliser une adresse IP différente de la sienne) n'est pas interdite. Le réseau TOR étant conçu par couche de proxy, il est difficile et à ma connaissance pour l'instant impossible d'arriver à remonter au client initial, donc de ce coté là notre anonymat est respecté.

En revanche si vous utilisez TOR comme serveur, et que vous devenez vous-même un proxy, un maillon de la chaîne, vous n'êtes toujours pas hors la loi, mais un risque apparaît. En effet si vous êtes le noeud final (la passerelle apparente) d'une personne qui va télécharger illégalement des oeuvres protégées, votre responsabilité devient engagé au titre de la clause "d'obligation de sécurisation de sa connection internet".

Pour résumé l'utilisation de TOR est autorisée (encore heureux), mais si vous devenez un noeuds du réseau ou plus précisément si vous devenez à un moment le noeud final de connection d'une personne, alors votre responsabilité devient engagée et vous risquez de vous prendre une lettre. Une proposition a été faite que seuls les pays "libre" devraient être des noeuds finaux sur le réseau, je pense que si on continue dans cette direction, il y a peut de chance qu'on reste dans cette liste.

Vale


Mar 25 2011

How to be a happy programmer (with Python) ? 2/3

In the series of the Python "features" that makes me happy last time i began with two concepts, the with statement and the list comprehensions, now i'm going to talk about Multiple assignments and the import aliases.
  • Multiple assignments

It's a simple idea that lets you return a series of value and on the other end assign those multiple values at the same time, example when you're splitting a string or extracting groups from a regular expression :

  1. >>> split_me ="here,we, are,again"
  2. # splitting we'll get a list of values
  3. >>> split_me.split(",")
  4. ['here', 'we', ' are', 'again']
  5. # if you don't know the number of values you're going to have
  6. # you can't use this features, example :
  7. >>> (start,end) = split_me.split(",")
  8. Traceback (most recent call last):
  9.   File "", line 1, in
  10. ValueError: too many values to unpack
  11. # but if you know that there's going to be n values :
  12. >>> (start,end) = split_me.split(" ")
  13. >>> start
  14. 'here,we,'
  15. >>> end
  16. 'are,again'
  • Import aliases

It means what it says, when you import a library or module, you can use aliases, example in Django for shortcuts :

  1. # this is extracted from my own code :
  2. from django.http import HttpResponse, HttpResponseRedirect as redirect
  3. from django.shortcuts import render_to_response as render
I won't start to talk about the standard library as a whole, or libs like Numpy, Scypy, scikit-learn, .... that makes it so easy to just think in Python.
And you ? What are the Python constructs (2.x or 3.x) that makes you feel happy and efficient at the end of the day ?

Mar 25 2011

Using TOR with Python

There are many occasion where you may be limited using your own IP address, i will obviously only refer myself to "rightful" cases where you need to use different IP address in very short lapse of time. Let's say you want to test your website localization functionality, or just access it using many different IP address and see how the system deals with it.

TOR is a wonderful tool for that. TOR (The Onion Ring to be specific) is a tool that allows you to use several IP addresses as gateways to connect to the Internet and change the path you use dynamically. It's main goal is to help you "Protect your privacy and defend yourself against network surveillance and traffic analysis.". I used it a long time ago, when connections were so bad, that using it was mostly a burden and not very practical.

But recently when i had to span HTTP requests through several IP address, i got frustrated by two facts :

  • First : i didn't have enough servers available to do it, and buying them from Amazon EC2 is not a solution as those servers may have the same IP address and all accounts are limited to 5 Elastic IP addresses and i don't want to buy myself for 400$ worth of servers i may use only 1 hour !
  • Second : i need to build a complex distributed environment (like a MapReduce job) and .... well i don't want to, i don't need parallel tasks, i just need a varying exit point.

So after a frustrating night of coding, i found myself thinking back of TOR. I installed it back again with Vidalia, and it worked ! Using Vidalia i could change my IP address when i needed and re-execute my tests with a brand new IP address. Of course it wasn't perfect as i was using sometimes 5 different relay points before reaching my goal but as i was not downloading anything heavy, it went well. But still, i had to change by hand my IP address. So the real point of this article is : " how to change dynamically your IP address using Python and TOR ?"

So first you need TOR installed, you can get it here : https://www.torproject.org/download/download.html.en and activate the remote control here  :

Then i'm going to assume you have Python, Git and Pip installed. To be clear on the principles of all this, TOR offers a relatively complex control system that you can connect to using Telnet, you can see the full command list and a few examples on the TOR website and here : http://thesprawl.org/memdump/?entry=8 . I'm going to refer only to the command i want to use : "re-new my route".

So to install TorCtl, the library we will want to use to control TOR, we'll clone the Git repository of the project, and install the library using Pip (it's pure laziness, i admit, because using python setup.py install works just fine too) :

  1. $ git clone git://github.com/aaronsw/pytorctl.git
  2. Cloning into pytorctl...
  3. remote: Counting objects: 555, done.
  4. remote: Compressing objects: 100% (180/180), done.
  5. remote: Total 555 (delta 376), reused 552 (delta 375)
  6. Receiving objects: 100% (555/555), 145.62 KiB | 213 KiB/s, done.
  7. Resolving deltas: 100% (376/376), done.
  8. $ pip install pytorctl/
  9. Unpacking ./pytorctl
  10.   Running setup.py egg_info for package from [...]
  11. Installing collected packages: torctl
  12.   Running setup.py install for torctl
  13. Successfully installed torctl
  14. Cleaning up...

So now if Tor is running and you try to do this :

  1. $ python
  2. Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
  3. [GCC 4.2.1 (Apple Inc. build 5646)] on darwin
  4. Type "help", "copyright", "credits" or "license" for more information.
  5. >>> from TorCtl import TorCtl
  6. >>> connection = TorCtl.connect(passphrase="lol")
  7. >>> connection.is_live()
  8. True

It's proof that it works, just use close() on the connection object to disconnect yourself. Now all we need to do is use this connection to send signals to TOR and tell urllib2 to use this precise connection, let's go :

  1. import urllib2
  2. # using TOR !
  3. proxy_support = urllib2.ProxyHandler({"http" : "127.0.0.1:8118"} )
  4. opener = urllib2.build_opener(proxy_support)
  5. urllib2.install_opener(opener)
  6. # every urlopen connection will then use the TOR proxy like this one :
  7. urllib2.urlopen('http://www.google.fr').read()
  8. # and to renew my route when i need to change the IP :
  9. print "Renewing tor route wait a bit for 5 seconds"
  10. from TorCtl import TorCtl
  11. conn = TorCtl.connect(passphrase="lol")
  12. conn.sendAndRecv('signal newnym\r\n')
  13. conn.close()
  14. import time
  15. time.sleep(5)
  16. print "renewed"

Now you know everything i know. On the receiving end, i don't think there's that much data on how to identify the "source" of the request, if you've got any clue about that, tell me in the comments.

Vale


Mar 18 2011

How to be a happy programmer (with Python) ? 1/3

I've just watched Hillary Mason's talk in Pycon 2011 : http://pycon.blip.tv/file/4878710/
And that got me thinking about all the python constructs that makes my day better, and i decided to make a list of them and their meaning.

  • With

The with keyword is the equivalent of the whole try, catch, finally triplets in Java to handle resources (files, database connections, remote connections, anything that can fail). So the with statement is here to make sure that, for example using a database connection, transaction is started and stopped correctly and can be used as follow :

  1. with open('/tmp/my_file', 'w') as p:
  2.      p.write('Writing in a properly closed file resource.')

For a few more example python-with-statement, the official presentation for What's new in 2.5 and if you want to know more in order to implement objects usable with the "with" statement, you need to see how the context managers work

  • List comprehensions

I shouldn't even have to explain how much joy you can gain from using these, especially when you're dealing with object oriented programming or immutable objects, well pretty much anytime you need to operate simple transformation on Lists, dictionnaries, anything iterable, list comprehension is not only the most beautiful way, but also many times, the most efficient way. So here we go for an example :

  1. >>> words = 'The quick brown fox jumps over the lazy dog'.split()
  2. >>> print words
  3. ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
  4. >>>
  5. >>> stuff = [[w.upper(), w.lower(), len(w)] for w in words]
  6. >>> for i in stuff:
  7. ...     print i
  8. ...
  9. ['THE', 'the', 3]
  10. ['QUICK', 'quick', 5]
  11. ['BROWN', 'brown', 5]
  12. ['FOX', 'fox', 3]
  13. ['JUMPS', 'jumps', 5]
  14. ['OVER', 'over', 4]
  15. ['THE', 'the', 3]
  16. ['LAZY', 'lazy', 4]
  17. ['DOG', 'dog', 3]

This was the first part of 3 showing  the few Python syntax constructs that makes me "not" scream when i try to do things and i don't want to lose time ! See you next time.

Vale


Mar 15 2011

How to debug Django using the Python Debugger PDB

Even if that seems common sense, i found out that there's not that much sources that explains how to use PDB with Django's bundle webserver.  So here we go, let's say you have some treatment like that :

  1. def search(request):
  2.         """
  3.                 search (it's written up there).
  4.         """
  5.         if request.method == 'POST':
  6.                 item = request.POST['item']
  7.                 # separate numeric part from string part and
  8.                 # add a % in case no numeric value is provided
  9.                 (num, test) = re.match("([\d]*)([\D]*)", item).groups()
  10.                 if not num:
  11.                         num = "%"
  12.                 .... # query in database

Now what we want to check, is that the "not num" part is doing its job in replacing any non-numeric part by a wildcard. so we'll add this statement "import pdb; pdb.set_trace()" to set up a breakpoint that PDB will be able to use :

  1. def search(request):
  2.         """
  3.                 ase.
  4.         """
  5.         if request.method == 'POST':
  6.                 item = request.POST['item']
  7.                 # separate numeric part from string part and
  8.                 # add a % in case no numeric value is provided
  9.                 (num, test) = re.match("([\d]*)([\D]*)", item).groups()
  10.                 # the breakpoint will be here :
  11.                 import pdb; pdb.set_trace()
  12.                 if not num:
  13.                         num = "%"
  14.                 .... # query in database

And then, all we need to do is run the standalone embedded web server of Django using pdb. At first PDB (just like GDB) will wait for you to use the command c (continue) to launch the program and will only stop when he reaches a breakpoint :

  1. python -m pdb manage.py runserver

Eventually when you'll reach the breakpoint, you can use the commands locals(), globals() to see all the variables you can access. For more on how to use PDB and debugging in Django i refer you to the nice tutorial by Mike Tigas.

Vale


Mar 10 2011

[IncidentsRATP] Suite et bientôt fin

J'avais déjà publié à la fois la lettre de la RATP me mettant en demeure de fermer le site incidents-ratp.com et mon ressenti sur toute cette affaire, mais là l'histoire continue.

Pour résumer ce qu'il s'est passé par la suite, j'ai pris contact avec un avocat et nous avons rédigé une réponse à la RATP sur les trois points qu'elle imposait pour un règlement à l'amiable, à savoir :

  • Rendre le nom de domaine gratuitement ;
  • Cesser toute activité autour ce service ; (relisez la lettre de la RATP si vous n'en êtes pas convaincu)
  • Et signer une promesse de ne jamais enfreindre les lois de la propriété intellectuelle vis-à-vis de la RATP...

Le premier point m'a toujours paru légitime, et si une erreur a été faite, j'en assume les conséquences. Ma décision de prendre un avocat a été motivé précisément par le deuxième point que je trouvais inacceptable. La réponse que nous avons fait avec mon avocat reprenait ces trois points en disant explicitement :

  • Si vous voulez ;
  • C'est un "non ferme et définitif" ;
  • Si vous voulez.

Si j'insiste sur ce deuxième c'est précisément parce que la RATP dans sa lettre de réponse nie jusqu'à l'existence de cette clause et nous fait croire à une mauvaise interprétation de notre part :

A l'attention de Maître *************

Cher Maître,

Nous faisons suite à votre courrier recommandé du 1er mars 2011.

Nous avons bien noté l’accord de votre client pour transférer le  nom
de domaine « www.incidents-ratp.com » à titre gratuit à la RATP et
vous invitons à contacter notre Registrar à cet effet par téléphone ou
par mail aux coordonnées suivantes :

******************
Tél. : ************
Mail : ***********

Nous vous remercions parallèlement de nous adresser la lettre
d’engagement ci-jointe, dûment signée par M. Girardot.

En ce qui concerne le site de votre Client per se,  nous insistons sur
le fait que la RATP n’a jamais envisagé de contester son existence ou
son exploitation, dès lors qu’aucun élément ne vient le présenter
comme un site officiel de la RATP.

La reproduction du nom de la RATP au sein du nom de domaine ou au sein
du site et/ou un environnement graphique susceptible de créer un
risque de confusion dans l’esprit du public avec un site émanant de la
RATP lui sont en revanche préjudiciables et à ce titre sont
inacceptables, vous en conviendrez.

Nous attendons donc le transfert du nom de domaine «
www.incidents-ratp.com » au plus vite et en tout état de cause, avant
le 15 mars 2011, ainsi que la lettre d’engagement susmentionnée signée
par votre Client.

Dans l’attente de votre retour, nous vous prions de croire, cher
Maître, en l’expression de nos sincères salutations.

********

RATP - Département Juridique
Affaires commerciales et Propriété Intellectuelle
<<adresse>>

Avec ci-joint la belle lettre d'engagement qu'on me propose, avec l'amabilité d'un braqueur, de signer sans bonjour ni merci : lettre d'engagement - RATP.

Je vous laisse juger sur pièces, mais le fait est que l'on a encore un long chemin à parcourir pour que la transparence et l'OpenData fasse son chemin dans les esprits.

Pendant ce temps là, sur le RER A : http://gnafrone.wordpress.com/2011/03/10/coincee-dans-le-rer-a-pour-bien-commencer-sa-journee/

Vale