diff --git a/freeradius/auth.py b/freeradius/auth.py index c2cae51a..a48de8aa 100644 --- a/freeradius/auth.py +++ b/freeradius/auth.py @@ -10,6 +10,8 @@ import netaddr import radiusd # Module magique freeradius (radiusd.py is dummy) import ldap import os +import binascii +import hashlib import lc_ldap.shortcuts from lc_ldap.crans_utils import escape as escape_ldap @@ -80,7 +82,7 @@ use_ldap_admin = lc_ldap.shortcuts.with_ldap_conn(retries=2, delay=5, use_ldap = lc_ldap.shortcuts.with_ldap_conn(retries=2, delay=5, constructor=lc_ldap.shortcuts.lc_ldap_anonymous) -def radius_event(f): +def radius_event(fun): """Décorateur pour les fonctions d'interfaces avec radius. Une telle fonction prend un uniquement argument, qui est une liste de tuples (clé, valeur) et renvoie un triplet dont les composantes sont : @@ -102,7 +104,7 @@ def radius_event(f): # Ex: Calling-Station-Id: "une_adresse_mac" data[key] = value.replace('"', '') try: - return f(data) + return fun(data) except Exception as e: logger.error(repr(e) + ' on data ' + repr(auth_data)) raise @@ -256,7 +258,7 @@ def register_machine(data, machine, conn): @radius_event @use_ldap_admin @use_ldap -def instantiate(p, *conns): +def instantiate(_, *conns): """Utile pour initialiser les connexions ldap une première fois (otherwise, do nothing)""" logger.info('Instantiation') @@ -311,10 +313,39 @@ def authorize_wifi(data): @radius_event def authorize_fil(data): - """For now, do nothing. - TODO: check BL_REJECT. - TODO: check chap auth """ + Check le challenge chap, et accepte. + TODO: check BL_REJECT. + """ + + chap_ok = False + # Teste l'authentification chap fournie + # password et challenge doivent être données + # en hexa (avec ou sans le 0x devant) + # le User-Name est en réalité la mac ( xx:xx:xx:xx:xx ) + password = data.get('CHAP-Password', '') + challenge = data.get('CHAP-Challenge', '') + mac = data.get('User-Name', '') + + logger.debug('(fil) authorize(%r)' % ((password, challenge, mac),)) + + try: + challenge = binascii.a2b_hex(challenge.replace('0x','')) + password = binascii.a2b_hex(password.replace('0x','')) + if hashlib.md5(password[0] + mac + challenge).digest() == password[1:]: + logger.info("(fil) Chap ok") + chap_ok = True + else: + logger.info("(fil) Chap wrong") + except: + logger.info("(fil) Chap challenge check failed") + + if not chap_ok: + if DEBUG: + logger.debug('(fil) Continue auth (debug)') + else: + return radiusd.RLM_MODULE_REJECT + return (radiusd.RLM_MODULE_UPDATED, (), ( @@ -546,25 +577,8 @@ def decide_vlan(data, is_wifi, conn): def dummy_fun(p): return radiusd.RLM_MODULE_OK -def detach(p=None): +def detach(_=None): """Appelé lors du déchargement du module (enfin, normalement)""" print "*** goodbye from auth.py ***" return radiusd.RLM_MODULE_OK -# à réimplémenter dans le authorize -# chap_ok(os.getenv('CHAP_PASSWORD'), os.getenv('CHAP_CHALLENGE'), mac) -def chap_ok(password, challenge, clear_pass) : - """ Test l'authentification chap fournie - password et chalenge doivent être données - en hexa (avec ou sans le 0x devant) - - retourne True si l'authentification est OK - retourne False sinon - """ - try : - challenge = binascii.a2b_hex(challenge.replace('0x','')) - password = binascii.a2b_hex(password.replace('0x','')) - if hashlib.md5(password[0] + clear_pass + challenge).digest() == password[1:] : - return True - except : - return False