diff --git a/radius_auth.py b/radius_auth.py index 6e01bd7f..485b7046 100644 --- a/radius_auth.py +++ b/radius_auth.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import os, hashlib, sys, binascii from syslog import syslog, openlog @@ -7,6 +7,7 @@ from syslog import syslog, openlog sys.path.append('/usr/scripts/gestion') from ldap_crans import crans_ldap, AssociationCrans, Club from config import ann_scol, dat, vlans, periode_transitoire +import annuaires_pg from iptools import AddrInNet def chap_ok(password, challenge, clear_pass) : """ Test l'authentification chap fournie @@ -24,7 +25,17 @@ def chap_ok(password, challenge, clear_pass) : except : return False -def do_auth(mac): +def paiement_ok(adh): + """Paiment ok ?""" + global ann_scol + paid = max(adh.paiement() + [0]) + if periode_transitoire: + # Si periode transitoire, on accepte les personnes n'ayant pas + # réadhéré + ann_scol -= 1 + return ann_scol <= paid + +def do_auth(mac, prise): """Effectue l'authentification. Renvoie (success, msg, vlan). success est 0 si l'authentification est réussie, msg est pour les logs et vlan est le vlan non taggé à utiliser pour la @@ -32,11 +43,13 @@ def do_auth(mac): global ann_scol + # Test chap (comme cela on est sur que c'est bien un switch qui demande) if not chap_ok(os.getenv('CHAP_PASSWORD'), os.getenv('CHAP_CHALLENGE'), mac): return (-1, "Échec test CHAP", "") # Mac dans la base LDAP - m = crans_ldap(readonly=True).search('mac=%s' % mac)['machine'] + conn = crans_ldap(readonly=True) + m = conn.search('mac=%s' % mac)['machine'] if len(m) == 0: return (0, "Mac inconnue", "accueil") elif len(m) > 1: @@ -58,20 +71,24 @@ def do_auth(mac): or 'autodisc_virus' in m[0].blacklist_actif()): return (0, "Bad boy", "isolement") - # L'adherent ne paie pas, on le met sur le vlan radin - if ((not isinstance(proprio, Club) and not proprio.adherentPayant()) or \ - ('Nounou' in proprio.droits() and AddrInNet(m[0].ip(),'10.42.0.0/16'))): - return (0, "Ne paie pas", "gratuit") - - # Paiment ok ? - paid = max(proprio.paiement() + [0]) - if periode_transitoire: - # Si periode transitoire, on accepte les personnes n'ayant pas - # réadhéré - ann_scol -= 1 - if ann_scol > paid: + # Paiement proprio ? + if not paiement_ok(proprio): return (0, "N'a pas payé", "accueil") + # Si l'adhérent n'est pas membre actif, il doit se brancher depuis la prise + # d'un autre adhérent à jour de cotisation + if not proprio.droits(): + try: + chbre = prise[0] + annuaires_pg.reverse(prise[0], prise[1:])[0] + except IndexError: + return (0, "Chambre inconnue", "accueil") + hebergeurs = conn.search('chambre=' + chbre) + for hebergeur in hebergeurs['adherent'] + hebergeurs['club']: + if paiement_ok(hebergeur): + break + else: + return (0, "Hébergeur non à jour", "accueil") + # Cas des personnels logés dans les appartements de l'ENS if (proprio.etudes(0) == 'Personnel ENS' or ('Nounou' in proprio.droits() and AddrInNet(m[0].ip(),'10.2.9.0/24'))): @@ -81,17 +98,16 @@ def do_auth(mac): return (0, "Accès adhérent OK", "adherent") if __name__ == '__main__' : - # Test chap (comme cela on est sur que c'est bien un switch qui demande) mac = os.getenv('USER_NAME', '').replace('"', '') - - # On vérifie si la mac est autorisée - (r, msg, vlan) = do_auth(mac) - - # On logue la prise sur laquelle a lieu la tentative - openlog("radius_auth.py") switch = os.getenv("NAS_IDENTIFIER", "").replace('"', '').split('.')[0] prise = (len(switch) == 6 and (switch[3] + switch[5]) or (switch + "-")) prise += "%02d" % int(os.getenv("NAS_PORT", 0)) + + # On vérifie si la mac est autorisée + (r, msg, vlan) = do_auth(mac, prise) + + # On logue la prise sur laquelle a lieu la tentative + openlog("radius_auth.py") syslog("%s -> %s [%s]" % (prise, mac, msg)) if vlan: