From 9551545593b5113f081fb31c6a45d2a732376fbd Mon Sep 17 00:00:00 2001 From: Daniel STAN Date: Fri, 9 Nov 2012 02:28:45 +0100 Subject: [PATCH] =?UTF-8?q?[radius=5Fauth]=20Auth=20possible=20uniquement?= =?UTF-8?q?=20depuis=20une=20chbre=20d'adh=C3=A9rent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ignore-this: 1977068e83e9be1619fb8b946433c61d Sauf pour les membres actifs (tests de maintenance, toussa) Au passage, il faudrait rajouter aussi une limitation au niveau des machines clubs, qui ne devraient pouvoir être connectées que sur la prise dudit club. darcs-hash:20121109012845-28565-25619e6a508450c2f9fbb00c2a0ae81e63ece194.gz --- radius_auth.py | 60 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 22 deletions(-) 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: