import sys import subprocess import time import ldap sys.path.append('/usr/scripts/') 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', 'ex_crous': 'ERR_CUSTOM_EX_CROUS.html', 'ex_crous_enable': 'ERR_CUSTOM_EX_CROUS_ENABLE.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', 'paiement': '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', 'paiement', 'inscrit' ] def mac_from_ip(ip): if ip == "10.51.0.10": return u"02:72:6f:75:74:07" 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.strip() else: return None def enable_access(ip): """Lance la commande idoine pour autoriser l'adresse IP""" p = subprocess.Popen(['sudo', '-n', '/usr/scripts/utils/install-party/ipset_allow', ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() if out or err: print "ipset_allow:" print out print "---" print err return False return True 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(u'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(u'macAddress=%s' % mac_addr, mode='rw')[0] # machine.set_ipv4() return machines def get_machine_by_ip(ip): return get(u'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 special(action, ip, environ, start_response): mac = mac_from_ip(ip) url = "https://intranet2.crans.org/machines/add/" if 'wifi' in action: url += 'wifi/' else: url += 'fil/' if mac is not None: url += mac + '/' start_response("302 OK", [ ("Content-Type", "text/html"), ("Cache-Control", "no-cache, must-revalidate"), ("Expires", "Thu, 01 Jan 1970 00:00:00 GMT"), ("Location", url), ("Content-Length", 0) ]) return "" 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 environ.get('RAW_URI', '').startswith('/special'): return special(environ.get('RAW_URI','')[9:], ip, environ, start_response) if AddrInNet(ip, '10.231.137.0/24'): if environ.get('RAW_URI', '').startswith('/enable'): enable_access(ip) data = deco['ex_crous_enable'] else: data = deco['ex_crous'] elif 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 ""