8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-25 04:43:10 +00:00

Merge branch 'stack_radius' into 'master'

Added Juniper Stacks support and optimized auth.py

See merge request federez/re2o!42
This commit is contained in:
chirac 2017-12-03 19:56:26 +01:00
commit 0dca51bed3

View file

@ -3,7 +3,7 @@
# se veut agnostique au réseau considéré, de manière à être installable en # se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics. # quelques clics.
# #
# Copyirght © 2017 Daniel Stan # Copyirght © 2017 Daniel Stan
# Copyright © 2017 Gabriel Détraz # Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec # Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle # Copyright © 2017 Augustin Lemesle
@ -127,7 +127,7 @@ def radius_event(fun):
return new_f return new_f
@radius_event @radius_event
def instantiate(*_): def instantiate(*_):
@ -155,7 +155,7 @@ def authorize(data):
user = data.get('User-Name', '').decode('utf-8', errors='replace') user = data.get('User-Name', '').decode('utf-8', errors='replace')
user = user.split('@', 1)[0] user = user.split('@', 1)[0]
mac = data.get('Calling-Station-Id', '') mac = data.get('Calling-Station-Id', '')
result, log, password = check_user_machine_and_register(nas_type, user, mac) result, log, password = check_user_machine_and_register(nas_type, user, mac)
logger.info(log.encode('utf-8')) logger.info(log.encode('utf-8'))
logger.info(user.encode('utf-8')) logger.info(user.encode('utf-8'))
@ -189,13 +189,20 @@ def post_auth(data):
if not nas_type: if not nas_type:
logger.info(u"Type de nas non enregistré dans la bdd!".encode('utf-8')) logger.info(u"Type de nas non enregistré dans la bdd!".encode('utf-8'))
return radiusd.RLM_MODULE_OK return radiusd.RLM_MODULE_OK
mac = data.get('Calling-Station-Id', None) mac = data.get('Calling-Station-Id', None)
# Si il s'agit d'un switch # Si il s'agit d'un switch
if hasattr(nas_instance, 'switch'): if hasattr(nas_instance, 'switch'):
port = data.get('NAS-Port-Id', data.get('NAS-Port', None)) port = data.get('NAS-Port-Id', data.get('NAS-Port', None))
# Hack, à cause d'une numérotation cisco baroque #Pour les infrastructures possédant des switchs Juniper :
#On vérifie si le switch fait partie d'un stack Juniper
instance_stack = nas_instance.switch.stack
if instance_stack:
# Si c'est le cas, on resélectionne le bon switch dans la stack
id_stack_member = port.split("-")[1].split('/')[0]
nas_instance = Interface.objects.filter(switch__in=Switch.objects.filter(stack=instance_stack).filter(stack_member_id=id_stack_member)).select_related('domain__extension').first()
# On récupère le numéro du port sur l'output de freeradius. La ligne suivante fonctionne pour cisco, HP et Juniper
port = port.split(".")[0].split('/')[-1][-2:] port = port.split(".")[0].split('/')[-1][-2:]
out = decide_vlan_and_register_switch(nas_instance, nas_type, port, mac) out = decide_vlan_and_register_switch(nas_instance, nas_type, port, mac)
sw_name, reason, vlan_id = out sw_name, reason, vlan_id = out
@ -228,7 +235,7 @@ def detach(_=None):
return radiusd.RLM_MODULE_OK return radiusd.RLM_MODULE_OK
def find_nas_from_request(nas_id): def find_nas_from_request(nas_id):
nas = Interface.objects.filter(Q(domain=Domain.objects.filter(name=nas_id)) | Q(ipv4=IpList.objects.filter(ipv4=nas_id))) nas = Interface.objects.filter(Q(domain=Domain.objects.filter(name=nas_id)) | Q(ipv4=IpList.objects.filter(ipv4=nas_id))).select_related('type').select_related('switch__stack')
return nas.first() return nas.first()
def check_user_machine_and_register(nas_type, username, mac_address): def check_user_machine_and_register(nas_type, username, mac_address):
@ -257,7 +264,7 @@ def check_user_machine_and_register(nas_type, username, mac_address):
if result: if result:
return (True, u'Access Ok, Capture de la mac...', user.pwd_ntlm) return (True, u'Access Ok, Capture de la mac...', user.pwd_ntlm)
else: else:
return (False, u'Erreur dans le register mac %s' % reason, '') return (False, u'Erreur dans le register mac %s' % reason, '')
else: else:
return (False, u'Machine inconnue', '') return (False, u'Machine inconnue', '')
else: else:
@ -294,12 +301,11 @@ def decide_vlan_and_register_switch(nas, nas_type, port_number, mac_address):
sw_name = str(nas) sw_name = str(nas)
port = Port.objects.filter(switch=Switch.objects.filter(switch_interface=nas), port=port_number) port = Port.objects.filter(switch=Switch.objects.filter(switch_interface=nas), port=port_number).first()
#Si le port est inconnu, on place sur le vlan defaut #Si le port est inconnu, on place sur le vlan defaut
if not port: if not port:
return (sw_name, u'Port inconnu', VLAN_OK) return (sw_name, u'Port inconnu', VLAN_OK)
port = port.first()
# Si un vlan a été précisé, on l'utilise pour VLAN_OK # Si un vlan a été précisé, on l'utilise pour VLAN_OK
if port.vlan_force: if port.vlan_force:
DECISION_VLAN = int(port.vlan_force.vlan_id) DECISION_VLAN = int(port.vlan_force.vlan_id)
@ -327,7 +333,7 @@ def decide_vlan_and_register_switch(nas, nas_type, port_number, mac_address):
if port.radius == 'COMMON' or port.radius == 'STRICT': if port.radius == 'COMMON' or port.radius == 'STRICT':
# Authentification par mac # Authentification par mac
interface = Interface.objects.filter(mac_address=mac_address) interface = Interface.objects.filter(mac_address=mac_address).select_related('machine__user').select_related('ipv4').first()
if not interface: if not interface:
# On essaye de register la mac # On essaye de register la mac
if not nas_type.autocapture_mac: if not nas_type.autocapture_mac:
@ -348,9 +354,8 @@ def decide_vlan_and_register_switch(nas, nas_type, port_number, mac_address):
if result: if result:
return (sw_name, u'Access Ok, Capture de la mac...' + extra_log, DECISION_VLAN) return (sw_name, u'Access Ok, Capture de la mac...' + extra_log, DECISION_VLAN)
else: else:
return (sw_name, u'Erreur dans le register mac %s' % reason + unicode(mac_address), VLAN_NOK) return (sw_name, u'Erreur dans le register mac %s' % reason + unicode(mac_address), VLAN_NOK)
else: else:
interface = interface.first()
if not interface.is_active: if not interface.is_active:
return (sw_name, u'Machine non active / adherent non cotisant', VLAN_NOK) return (sw_name, u'Machine non active / adherent non cotisant', VLAN_NOK)
elif not interface.ipv4: elif not interface.ipv4:
@ -358,5 +363,3 @@ def decide_vlan_and_register_switch(nas, nas_type, port_number, mac_address):
return (sw_name, u"Ok, Reassignation de l'ipv4" + extra_log, DECISION_VLAN) return (sw_name, u"Ok, Reassignation de l'ipv4" + extra_log, DECISION_VLAN)
else: else:
return (sw_name, u'Machine OK' + extra_log, DECISION_VLAN) return (sw_name, u'Machine OK' + extra_log, DECISION_VLAN)