From 218f30957e4f797d99e0fec3c4295929a9fb04ee Mon Sep 17 00:00:00 2001 From: Valentin Samir Date: Sat, 25 May 2013 16:10:03 +0200 Subject: [PATCH] =?UTF-8?q?[portail=5Fcaptif]=20Ajout=20du=20script=20?= =?UTF-8?q?=C3=A0=20/usr/scripts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Permet de dire à nginx sur routeur quelle page afficher --- utils/portail_captif.py | 157 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 utils/portail_captif.py diff --git a/utils/portail_captif.py b/utils/portail_captif.py new file mode 100644 index 00000000..ae5f7854 --- /dev/null +++ b/utils/portail_captif.py @@ -0,0 +1,157 @@ +import sys +import subprocess +import time +import ldap +sys.path.append('/usr/scripts/') +sys.path.append('/etc/crans/secrets/') +sys.path.append('/etc/gunicorn/py') + +import lc_ldap.shortcuts +import lc_ldap.objets +from iptools import AddrInNet, NetSubnets, IpSubnet +def _get_ldap_connection(): + return lc_ldap.shortcuts.lc_ldap_readonly(user=u'root') +QUERY = _get_ldap_connection() + +cache={} +cache_time=60.0 +cleanup_time=3600.0 +next_cleanup=time.time() + cleanup_time + +def cleanup(now): + global cleanup_time, cache, cache_time, next_cleanup + if next_cleanup < now: + for ip in cache.keys(): + if cache[ip]['time']<(now - cache_time): + del cache[ip] + next_cleanup=time.time() + cleanup_time + + + +deco={ + 'non_inscrit': 'ERR_CUSTOM_NON_INSCRIT.html', + 'inscrit': 'ERR_CUSTOM_INSCRIT.html', + + 'age': 'ERR_CUSTOM_AGE.html', + 'ago': 'ERR_CUSTOM_AGO.html', + + 'autodisc_p2p': 'ERR_CUSTOM_BL_AUTO_P2P.html', + 'p2p':'ERR_CUSTOM_BL_P2P.html', + 'autodisc_upload':'ERR_CUSTOM_BL_AUTO_UPLOAD.html', + 'upload':'ERR_CUSTOM_BL_UPLOAD.html', + 'chambre_invalide': 'ERR_CUSTOM_BL_CHAMBRE.html', + 'carte_etudiant':'ERR_CUSTOM_BL_NO_CARTE.html', + 'mail_invalide':'ERR_CUSTOM_BL_NO_MAIL.html', + 'mail_invalide_inscription':'ERR_DISABLED_CUSTOM_BL_NO_MAIL.html', + 'warez':'ERR_CUSTOM_BL_WAREZ.html', + 'bloq':'ERR_CUSTOM_BLOQ.html', + + 'nouvelle_annee':'ERR_CUSTOM_NOUVELLE_ANNEE.html', + 'proxy_local':'ERR_CUSTOM_PROXY_LOCAL.html', + + 'virus':'ERR_CUSTOM_BL_VIRUS.html', + 'ipv6_ra':'ERR_CUSTOM_RA.html', + 'autodisc_virus':'ERR_CUSTOM_BL_AUTO_VIRUS.html', +} + +for bl in deco.keys(): + deco[bl]="/crans-deco/%s" % deco[bl] + +blacklist_key = [ + 'non_inscrit', + 'age','ago', + 'virus','autodisc_virus','ipv6_ra', + 'p2p','autodisc_p2p','upload','autodisc_uplaod','warez', + 'carte_etudiant','chambre_invalide','mail_invalide', + 'bloq', + 'nouvelle_annee','proxy_local', + 'inscrit' + ] + +def mac_from_ip(ip): + cmd = '/usr/sbin/arp -na %s' % ip + p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + output, errors = p.communicate() + if output is not None : + mac_addr = output.split()[3] + return mac_addr + else: + return None + + +def get(str): + global QUERY + try: + return QUERY.search(str) + except ldap.SERVER_DOWN: + QUERY = _get_ldap_connection() + return QUERY.search(str) + +def get_machine_by_mac(ip): + mac_addr=mac_from_ip(ip) + machines = get('macAddress=%s' % mac_addr) + if machines and isinstance(machines[0], lc_ldap.objets.machineWifi): + if not 'ipHostNumber' in machines[0].attrs.keys(): + machine = QUERY.search('macAddress=%s' % mac_addr, mode='rw')[0] + machine.set_ipv4() + return machines + + +def get_machine_by_ip(ip): + return get('ipHostNumber=%s' % ip) + +def get_page(ip, by_mac=False, accueil=False): + try: + if by_mac: + machines=get_machine_by_mac(ip) + else: + machines=get_machine_by_ip(ip) + adherent=machines[0].proprio() + except IndexError: + return deco['non_inscrit'] + blacklist=[bl.value['type'] for bl in adherent.blacklist_actif()] + for machine in machines: + blacklist.extend([bl.value['type'] for bl in machine.blacklist_actif()]) + for bl in blacklist_key: + if bl in blacklist: + return deco[bl] + if accueil: + return deco['inscrit'] + return None + +def app(environ, start_response): + if 'HTTP_K_REAL_IP' in environ.keys(): + ip=environ['HTTP_K_REAL_IP'] + else: + ip=environ['HTTP_REAL_IP'] + now=time.time() + cleanup(now) + if ip in cache.keys() and cache[ip]['time']>(now - cache_time): + data=cache[ip]['page'] + else: + if AddrInNet(ip,'10.51.0.0/16'): + data=get_page(ip,True,True) + elif AddrInNet(ip,'10.52.0.0/16'): + page=get_page(ip,True) + if page: + data=page + else: + data=deco['autodisc_virus'] + elif AddrInNet(ip,'138.231.136.0/21') or AddrInNet(ip,'138.231.144.0/21') or AddrInNet(ip,'10.2.9.0/24'): + page=get_page(ip) + if page: + data=page + else: + data="/crans-proxy/" + else: + data = deco['non_inscrit'] + cache[ip]={'time':time.time(),'page':data} + start_response("200 OK", [ + ("Content-Type", "text/html"), + ("Cache-Control", "no-cache, must-revalidate"), + ("Expires", "Thu, 01 Jan 1970 00:00:00 GMT"), + ("X-Accel-Redirect", data), + ("Content-Length", 0) + ]) + + return ""