Open Wifi Auto Connect
Par Puyb, vendredi 11 décembre 2009 à 20:48 :: General :: #139 :: rss
Je ne sais pas si vous utilisez souvent des réseaux wifi qui filtrent l'accès en utilisant un portail de capture web pour vous authentifier ? Personnellement, j'utilise régulièrement le service FreeWifi de Free...Le principe de ces services est que le pare-feu bloque toutes les connexions qui ne sont pas authentifiés. Pour s'authentifier, il faut utiliser un navigateur Web, tenter de naviguer vers un site quelconque pour se faire rediriger vers la page d'authentification puis y entrer ses identifiants...
Comme je suis toujours plus fainéant, je viens de faire un petit script qui se charge de faire toutes ses étapes automatiquement. Le principe est de surveiller les connexions aux différents réseaux sans fils, et dès qu'un réseau est reconnu (que son nom est dans une liste), il se charge tout seul de récupérer la page du portail, puis de la renvoyer accompagnée des identifiants de connexion.
Utilisation :
- Téléchargez le fichier.
- Copiez le dans le dossier de votre choix.
- Créez le fichier de configuration. Il se nomme .OpenWifiAutoConnect, doit être placer dans votre dossier personnel (~) et est au format .ini. Les sections correspondent aux nom des réseaux. Les clefs correspondent au champs du formulaire ou il faut entrer une valeur. Par exemple:
[UnReseau] email=test@example.com pass=azerty [FreeWifi] login=1234567890 password=secret
- Ajoutez le programme au démarrage de votre session.

- Vérifier que les paquets (ubuntu / debian) suivant sont installé : python-dbus, python-notify et python-beautifulsoup
- Redémarrer votre session pour que le programme se lance
- Connectez vous à un réseau wifi et attendez que la magie s'opère. Une popup de notification vous préviendra du succès de l'authentification.
Comment ça marche ?
Avant tout, voici le code :
#!/usr/bin/env python
################################################################################
# OpenWifiAutoConnect - Stephane PUYBAREAU (puyb <at> puyb <dot> net) - 2008 #
# Fully automated authentication to capture portal based wifi networks. #
# Config file: ~/.OpenWifiAutoConnect - Format: ini #
# Section are network SSID (names) #
# key / value pair define user submited information (based on the html form) #
# #
# This software is provided under the terms of the GPL v3 licence. #
# See http://www.gnu.org/licenses/gpl.html for more information #
# #
# This software use python dbus bindings, pynotify and BeautifulSoup modules #
################################################################################
# The url the program will try to open hoping to be redirected to the portal
URL = 'http://perdu.com/'
import sys
import gobject
import dbus
import dbus.mainloop.glib
import urllib2, urllib
from BeautifulSoup import BeautifulSoup
import re
import ConfigParser
import os
import pynotify
def properties_changed_signal_handler(props):
if not props.has_key('ActiveConnections'):
return
for device_path in props['ActiveConnections']:
device = bus.get_object('org.freedesktop.NetworkManager', device_path)
device_props = device.GetAll("org.freedesktop.NetworkManager.Connection.Active", dbus_interface="org.freedesktop.DBus.Properties")
if device_props['Default']:
return
ap_path = device_props['SpecificObject']
if ap_path.startswith('/org/freedesktop/NetworkManager/AccessPoint/'):
ap = bus.get_object('org.freedesktop.NetworkManager', ap_path)
ssid = ap.Get("org.freedesktop.NetworkManager.AccessPoint", "Ssid", dbus_interface="org.freedesktop.DBus.Properties")
ssid = ''.join([chr(c) for c in ssid])
if ssid not in config.sections():
return
print ssid
device.connect_to_signal("PropertiesChanged", device_properties_changed_signal_handler(ssid), dbus_interface="org.freedesktop.NetworkManager.Connection.Active")
def device_properties_changed_signal_handler(ssid):
def handler(props):
if not props.has_key('State'):
return
if props['State'] != 2:
return
print ssid
section = dict(config.items(ssid))
if login(section):
txt = "Successfully logged on " + ssid
else:
txt = "Failled to log on " + ssid
n = pynotify.Notification("Open Wifi Auto Connect", txt, "dialog-warning")
n.set_urgency(pynotify.URGENCY_NORMAL)
n.set_timeout(10)
#n.add_action("clicked","Button text", callback_function, None)
n.show()
return handler
def login(values):
# build an http fetcher that support cookies
opener = urllib2.build_opener( urllib2.HTTPCookieProcessor() )
urllib2.install_opener(opener)
# try to open the portal page
f = opener.open(URL)
data = f.read()
redirect_url = f.geturl().split('?')[0]
f.close()
if redirect_url == URL:
return # Our request wasn't hijacked by the portal (maybe the wifi network isn't the default connection)
# parse the portal page
soup = BeautifulSoup(data)
form = soup.find('form')
if not form:
return # There's no form on this page
# creating the post values
login_post = {}
for input in form.findAll('input'):
if input.has_key('name'):
default = ''
if input.has_key('type') and input['type'] == 'checkbox':
default = 'on'
login_post[input['name']] = input.has_key('value') and input['value'] or default
login_post.update(values)
# guessing the post url
if not form.has_key('action'):
url = redirect_url
elif not form['action'].startswith('/'):
url = '/'.join(redirect_url.split('/')[:-1]) + '/' + form['action']
else:
url = '/'.join(redirect_url.split('/')[:3]) + form['action']
# GET ou POST ?
postBody = None
if form.has_key('method') and form['method'].lower() == 'post':
postBody = urllib.urlencode(login_post)
else:
url += '?' + urllib.urlencode(login_post).replace(' ', '+')
# submit the form
f = opener.open(url, postBody)
data = f.read()
f.close()
# Test if the login was a success
f = opener.open(URL)
data = f.read()
status = f.geturl() == URL
f.close()
return status
if __name__ == '__main__':
config = ConfigParser.RawConfigParser()
config.read(os.path.expanduser('~/.OpenWifiAutoConnect'))
pynotify.init( "Open Wifi Auto Connect" )
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
nm = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
nm.connect_to_signal("PropertiesChanged", properties_changed_signal_handler, dbus_interface="org.freedesktop.NetworkManager")
loop = gobject.MainLoop()
loop.run()
Le programme utilise D-Bus pour demander au NetworkManager de lui signaler chaque changement au niveau du réseau. A chaque changement, il tente de déterminer, toujours grâce à D-Bus, si ce reseau est un réseau Wifi et quel est son SSID. Si le réseau est dans le fichier de configuration, il attend que que le réseau soit correctement connecté pour lancer la fonction login avec les paramètres de connexion.
Cette fonction commence par mettre en place un client HTTP supportant les cookies (il est possible (FreeWifi le fait) que le portail nous envoie des cookies). Il tente d'ouvrir une page vers un site quelconque (en l'occurrence perdu.com. Le client supporte les redirections HTTP, il teste donc si la requette a été redirigé. Si c'est le cas, le HTML est analysé avec Beautiful Soup pour récupérer toutes les informations sur le formulaire. Elle sont modifiées avec les informations de connexion provenant du fichier de configuration. Puis, le formulaire est envoyé. Enfin, il vérifie si l'authentification à réussi en tentant de joindre à nouveau perdu.com...
Limitations :
- Ce programme ne fonctionnera pas si le SSID du réseau n'est pas toujours le même. J'ai cru comprendre que les réseaux Fon n'avait pas tous le même nom, si c'est le cas, ça ne fonctionnera pas (enfin, pas pour tous les réseau Fon, mais juste pour ceux dont on a donner les noms.
- Ce programme ne fonctionnera pas non plus si les noms des champs à remplire dans le formulaire sont variables.
- Enfin, ça ne fonctionnera pas non plus si il y a un captcha (une joli image où l'on doit jouer à Champolion pour deviner ce qu'il ya d'inscrit).
Voilà, j'espère que ça va servir à quelqu'un (d'autre que moi)... Si il y a un problème, n'hésitez pas à laisser un commentaire... Et si il n'y a pas de problème, vous pouvez aussi laisser un commentaire ;-)
Commentaires
1. Le mercredi 16 décembre 2009 à 17:08, par itichi
2. Le mercredi 16 décembre 2009 à 17:36, par Julien
3. Le mercredi 16 décembre 2009 à 18:46, par manatlan
4. Le mercredi 16 décembre 2009 à 19:20, par Bristow
5. Le mercredi 16 décembre 2009 à 22:41, par slamp
6. Le mercredi 16 décembre 2009 à 22:51, par neFAST
7. Le jeudi 17 décembre 2009 à 18:31, par Puyb
8. Le lundi 21 décembre 2009 à 01:16, par Julien
9. Le lundi 21 décembre 2009 à 18:24, par bricowifi
10. Le lundi 21 décembre 2009 à 20:57, par Puyb
11. Le jeudi 24 décembre 2009 à 12:41, par fernetbianca
12. Le dimanche 27 décembre 2009 à 16:46, par Jase
13. Le mardi 29 décembre 2009 à 23:56, par Puyb
14. Le jeudi 31 décembre 2009 à 11:48, par manatlan
15. Le dimanche 3 janvier 2010 à 19:24, par Puyb
16. Le mardi 26 janvier 2010 à 20:13, par dayedaye
17. Le samedi 6 février 2010 à 16:52, par manatlan
Ajouter un commentaire