freeradius: auth.py valide challenge chap

This commit is contained in:
Daniel STAN 2015-04-03 23:57:35 +02:00
parent 746e5db7b8
commit 1d3b136bed

View file

@ -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