[radius_auth] Auth possible uniquement depuis une chbre d'adhérent

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
This commit is contained in:
Daniel STAN 2012-11-09 02:28:45 +01:00
parent ab4dd1ad56
commit 9551545593

View file

@ -1,5 +1,5 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
import os, hashlib, sys, binascii import os, hashlib, sys, binascii
from syslog import syslog, openlog from syslog import syslog, openlog
@ -7,6 +7,7 @@ from syslog import syslog, openlog
sys.path.append('/usr/scripts/gestion') sys.path.append('/usr/scripts/gestion')
from ldap_crans import crans_ldap, AssociationCrans, Club from ldap_crans import crans_ldap, AssociationCrans, Club
from config import ann_scol, dat, vlans, periode_transitoire from config import ann_scol, dat, vlans, periode_transitoire
import annuaires_pg
from iptools import AddrInNet from iptools import AddrInNet
def chap_ok(password, challenge, clear_pass) : def chap_ok(password, challenge, clear_pass) :
""" Test l'authentification chap fournie """ Test l'authentification chap fournie
@ -24,7 +25,17 @@ def chap_ok(password, challenge, clear_pass) :
except : except :
return False 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, """Effectue l'authentification. Renvoie (success, msg,
vlan). success est 0 si l'authentification est réussie, msg est 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 pour les logs et vlan est le vlan non taggé à utiliser pour la
@ -32,11 +43,13 @@ def do_auth(mac):
global ann_scol 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): if not chap_ok(os.getenv('CHAP_PASSWORD'), os.getenv('CHAP_CHALLENGE'), mac):
return (-1, "Échec test CHAP", "") return (-1, "Échec test CHAP", "")
# Mac dans la base LDAP # 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: if len(m) == 0:
return (0, "Mac inconnue", "accueil") return (0, "Mac inconnue", "accueil")
elif len(m) > 1: elif len(m) > 1:
@ -58,20 +71,24 @@ def do_auth(mac):
or 'autodisc_virus' in m[0].blacklist_actif()): or 'autodisc_virus' in m[0].blacklist_actif()):
return (0, "Bad boy", "isolement") return (0, "Bad boy", "isolement")
# L'adherent ne paie pas, on le met sur le vlan radin # Paiement proprio ?
if ((not isinstance(proprio, Club) and not proprio.adherentPayant()) or \ if not paiement_ok(proprio):
('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:
return (0, "N'a pas payé", "accueil") 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 # Cas des personnels logés dans les appartements de l'ENS
if (proprio.etudes(0) == 'Personnel ENS' or if (proprio.etudes(0) == 'Personnel ENS' or
('Nounou' in proprio.droits() and AddrInNet(m[0].ip(),'10.2.9.0/24'))): ('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") return (0, "Accès adhérent OK", "adherent")
if __name__ == '__main__' : if __name__ == '__main__' :
# Test chap (comme cela on est sur que c'est bien un switch qui demande)
mac = os.getenv('USER_NAME', '').replace('"', '') 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] switch = os.getenv("NAS_IDENTIFIER", "").replace('"', '').split('.')[0]
prise = (len(switch) == 6 and (switch[3] + switch[5]) or (switch + "-")) prise = (len(switch) == 6 and (switch[3] + switch[5]) or (switch + "-"))
prise += "%02d" % int(os.getenv("NAS_PORT", 0)) 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)) syslog("%s -> %s [%s]" % (prise, mac, msg))
if vlan: if vlan: