|
|
|
@ -141,89 +141,65 @@ def instantiate(*_): |
|
|
|
|
|
|
|
@radius_event |
|
|
|
def authorize(data): |
|
|
|
"""Fonction qui aiguille entre nas, wifi et filaire pour authorize |
|
|
|
On se contecte de faire une verification basique de ce que contien la requète |
|
|
|
pour déterminer la fonction à utiliser""" |
|
|
|
return authorize_fil(data) |
|
|
|
|
|
|
|
|
|
|
|
@radius_event |
|
|
|
def authorize_fil(data): |
|
|
|
""" |
|
|
|
Check le challenge chap, et accepte. |
|
|
|
""" |
|
|
|
user = data.get('User-Name', None) |
|
|
|
# Pour les requetes proxifiees, on split |
|
|
|
nas_type = data.get('NAS-Port-Type', None) |
|
|
|
if nas_type == "Wireless-802.11": |
|
|
|
user = user.split('@', 1)[0] |
|
|
|
mac = data.get('Calling-Station-Id', None) |
|
|
|
nas = data.get('NAS-IP-Address', data.get('NAS-Identifier', None)) |
|
|
|
result, log, password = check_user_machine_and_register(nas, user, mac) |
|
|
|
|
|
|
|
if not result: |
|
|
|
return radiusd.RLM_MODULE_REJECT |
|
|
|
else: |
|
|
|
return (radiusd.RLM_MODULE_UPDATED, |
|
|
|
(), |
|
|
|
( |
|
|
|
(str("NT-Password"), str(password)), |
|
|
|
), |
|
|
|
) |
|
|
|
|
|
|
|
return (radiusd.RLM_MODULE_UPDATED, |
|
|
|
else: |
|
|
|
return (radiusd.RLM_MODULE_UPDATED, |
|
|
|
(), |
|
|
|
( |
|
|
|
("Auth-Type", "Accept"), |
|
|
|
), |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
@radius_event |
|
|
|
def post_auth(data): |
|
|
|
# On cherche quel est le type de machine, et quel sites lui appliquer |
|
|
|
if data.get('NAS-Port-Type', '')==u'Ethernet': |
|
|
|
return post_auth_fil(data) |
|
|
|
elif u"Wireless" in data.get('NAS-Port-Type', ''): |
|
|
|
return post_auth_wifi(data) |
|
|
|
|
|
|
|
@radius_event |
|
|
|
def post_auth_wifi(data): |
|
|
|
"""Appelé une fois que l'authentification est ok. |
|
|
|
On peut rajouter quelques éléments dans la réponse radius ici. |
|
|
|
Comme par exemple le vlan sur lequel placer le client""" |
|
|
|
port = data.get('NAS-Port-Id', data.get('NAS-Port', None)) |
|
|
|
nas = data.get('NAS-IP-Address', data.get('NAS-Identifier', None)) |
|
|
|
|
|
|
|
port, vlan_name, reason = decide_vlan(data, True) |
|
|
|
nas_instance = find_nas_from_request(nas).first() |
|
|
|
mac = data.get('Calling-Station-Id', None) |
|
|
|
|
|
|
|
log_message = '(wifi) %s -> %s [%s%s]' % \ |
|
|
|
(port, mac, vlan_name, (reason and u': ' + reason).encode('utf-8')) |
|
|
|
logger.info(log_message) |
|
|
|
|
|
|
|
# Si NAS ayant des mapping particuliers, à signaler ici |
|
|
|
vlan_id = config.vlans[vlan_name] |
|
|
|
|
|
|
|
# WiFi : Pour l'instant, on ne met pas d'infos de vlans dans la réponse |
|
|
|
# les bornes wifi ont du mal avec cela |
|
|
|
if WIFI_DYN_VLAN: |
|
|
|
|
|
|
|
# Si il s'agit d'un switch |
|
|
|
if hasattr(nas_instance, 'switch'): |
|
|
|
# Hack, à cause d'une numérotation cisco baroque |
|
|
|
port = port.split(".")[0].split('/')[-1][-2:] |
|
|
|
out = decide_vlan_and_register_switch(nas_instance, port, mac) |
|
|
|
sw_name, reason, vlan_id = out |
|
|
|
|
|
|
|
log_message = '(fil) %s -> %s [%s%s]' % \ |
|
|
|
(sw_name + u":" + port, mac, vlan_id, (reason and u': ' + reason).encode('utf-8')) |
|
|
|
logger.info(log_message) |
|
|
|
|
|
|
|
# Filaire |
|
|
|
return (radiusd.RLM_MODULE_UPDATED, |
|
|
|
( |
|
|
|
("Tunnel-Type", "VLAN"), |
|
|
|
("Tunnel-Medium-Type", "IEEE-802"), |
|
|
|
("Tunnel-Private-Group-Id", '%d' % vlan_id), |
|
|
|
("Tunnel-Private-Group-Id", '%d' % int(vlan_id)), |
|
|
|
), |
|
|
|
() |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
return radiusd.RLM_MODULE_OK |
|
|
|
|
|
|
|
@radius_event |
|
|
|
def post_auth_fil(data): |
|
|
|
"""Idem, mais en filaire. |
|
|
|
""" |
|
|
|
|
|
|
|
nas = data.get('NAS-IP-Address', data.get('NAS-Identifier', None)) |
|
|
|
port = data.get('NAS-Port-Id', data.get('NAS-Port', None)) |
|
|
|
mac = data.get('Calling-Station-Id', None) |
|
|
|
# Hack, à cause d'une numérotation cisco baroque |
|
|
|
port = port.split(".")[0].split('/')[-1][-2:] |
|
|
|
out = decide_vlan_and_register_macauth(nas, port, mac) |
|
|
|
sw_name, reason, vlan_id = out |
|
|
|
|
|
|
|
log_message = '(fil) %s -> %s [%s%s]' % \ |
|
|
|
(sw_name + u":" + port, mac, vlan_id, (reason and u': ' + reason).encode('utf-8')) |
|
|
|
logger.info(log_message) |
|
|
|
|
|
|
|
# Filaire |
|
|
|
return (radiusd.RLM_MODULE_UPDATED, |
|
|
|
( |
|
|
|
("Tunnel-Type", "VLAN"), |
|
|
|
("Tunnel-Medium-Type", "IEEE-802"), |
|
|
|
("Tunnel-Private-Group-Id", '%d' % int(vlan_id)), |
|
|
|
), |
|
|
|
() |
|
|
|
) |
|
|
|
# Il s'agit d'une borne WiFi |
|
|
|
else: |
|
|
|
return radiusd.RLM_MODULE_OK |
|
|
|
|
|
|
|
@radius_event |
|
|
|
def dummy_fun(_): |
|
|
|
@ -235,21 +211,58 @@ def detach(_=None): |
|
|
|
print "*** goodbye from auth.py ***" |
|
|
|
return radiusd.RLM_MODULE_OK |
|
|
|
|
|
|
|
def find_nas_from_request(nas_id): |
|
|
|
if not isinstance(nas_id, int): |
|
|
|
nas = Interface.objects.filter(domain=Domain.objects.filter(name=nas_id)) |
|
|
|
else: |
|
|
|
nas = Interface.objects.filter(ipv4=nas_id) |
|
|
|
return nas |
|
|
|
|
|
|
|
def check_user_machine_and_register(nas_id, username, mac_address): |
|
|
|
""" Verifie le username et la mac renseignee. L'enregistre si elle est inconnue. |
|
|
|
Renvoie le mot de passe ntlm de l'user si tout est ok |
|
|
|
Utilise pour les authentifications en 802.1X""" |
|
|
|
#nas = find_nas_from_request(nas_id).first() |
|
|
|
#if not nas: |
|
|
|
# return (False, 'Nas inconnu %s ' % nas_id, '') |
|
|
|
|
|
|
|
#ipv4 = nas.ipv4 |
|
|
|
|
|
|
|
interface = Interface.objects.filter(mac_address=mac_address).first() |
|
|
|
user = User.objects.filter(pseudo=username).first() |
|
|
|
if not user: |
|
|
|
return (False, "User inconnu", '') |
|
|
|
if not user.has_access: |
|
|
|
return (False, "Adherent non cotisant", '') |
|
|
|
if interface: |
|
|
|
if interface.machine.user != user: |
|
|
|
return (False, u"Machine enregistrée sur le compte d'un autre user...", '') |
|
|
|
elif not interface.is_active: |
|
|
|
return (False, u"Machine desactivée", '') |
|
|
|
else: |
|
|
|
return (True, "Access ok", user.pwd_ntlm) |
|
|
|
elif MAC_AUTOCAPTURE: |
|
|
|
result, reason = user.autoregister_machine(mac_address, ipv4.first()) |
|
|
|
if result: |
|
|
|
return (True, 'Access Ok, Capture de la mac...', user.pwd_ntlm) |
|
|
|
else: |
|
|
|
return (False, u'Erreur dans le register mac %s' % reason, '') |
|
|
|
else: |
|
|
|
return (False, "Machine inconnue", '') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def decide_vlan_and_register_macauth(switch_id, port_number, mac_address): |
|
|
|
|
|
|
|
def decide_vlan_and_register_switch(nas, port_number, mac_address): |
|
|
|
# Get port from switch and port number |
|
|
|
if not isinstance(switch_id, int): |
|
|
|
switch = Switch.objects.filter(switch_interface=Interface.objects.filter(domain=Domain.objects.filter(name=switch_id))) |
|
|
|
else: |
|
|
|
switch = Switch.objects.filter(switch_interface=Interface.objects.filter(ipv4=switch_id)) |
|
|
|
if not switch: |
|
|
|
return ('?', 'Switch inconnu', VLAN_OK) |
|
|
|
if not nas: |
|
|
|
return ('?', 'Nas inconnu', VLAN_OK) |
|
|
|
|
|
|
|
ipv4 = switch.first().switch_interface.ipv4 |
|
|
|
ipv4 = nas.ipv4 |
|
|
|
|
|
|
|
sw_name = str(switch.first().switch_interface) |
|
|
|
sw_name = str(nas) |
|
|
|
|
|
|
|
port = Port.objects.filter(switch=switch.first(), port=port_number) |
|
|
|
port = Port.objects.filter(switch=Switch.objects.filter(switch_interface=nas), port=port_number) |
|
|
|
if not port: |
|
|
|
return (sw_name, 'Port inconnu', VLAN_OK) |
|
|
|
|
|
|
|
@ -288,7 +301,7 @@ def decide_vlan_and_register_macauth(switch_id, port_number, mac_address): |
|
|
|
elif not room_user.first().has_access(): |
|
|
|
return (sw_name, 'Machine inconnue et adhérent non cotisant', VLAN_NOK) |
|
|
|
else: |
|
|
|
result, reason = room_user.first().autoregister_machine(mac_address, ipv4.first()) |
|
|
|
result, reason = room_user.first().autoregister_machine(mac_address, ipv4) |
|
|
|
if result: |
|
|
|
return (sw_name, 'Access Ok, Capture de la mac...', VLAN_OK) |
|
|
|
else: |
|
|
|
@ -301,3 +314,5 @@ def decide_vlan_and_register_macauth(switch_id, port_number, mac_address): |
|
|
|
# On gere bien tous les autres états possibles, il ne reste que le VLAN en dur |
|
|
|
return (sw_name, 'VLAN impose', int(port.radius)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|