8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-26 08:53:46 +00:00

Gestion de l'authentification wifi dans auth.py et enregistrement des macs

This commit is contained in:
Gabriel Detraz 2017-09-12 17:40:04 +00:00 committed by root
parent 13357cec50
commit 3bb0c917f3

View file

@ -141,89 +141,65 @@ def instantiate(*_):
@radius_event @radius_event
def authorize(data): def authorize(data):
"""Fonction qui aiguille entre nas, wifi et filaire pour authorize user = data.get('User-Name', None)
On se contecte de faire une verification basique de ce que contien la requète # Pour les requetes proxifiees, on split
pour déterminer la fonction à utiliser""" nas_type = data.get('NAS-Port-Type', None)
return authorize_fil(data) 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)),
),
)
@radius_event else:
def authorize_fil(data): return (radiusd.RLM_MODULE_UPDATED,
"""
Check le challenge chap, et accepte.
"""
return (radiusd.RLM_MODULE_UPDATED,
(), (),
( (
("Auth-Type", "Accept"), ("Auth-Type", "Accept"),
), ),
) )
@radius_event @radius_event
def post_auth(data): def post_auth(data):
# On cherche quel est le type de machine, et quel sites lui appliquer port = data.get('NAS-Port-Id', data.get('NAS-Port', None))
if data.get('NAS-Port-Type', '')==u'Ethernet': nas = data.get('NAS-IP-Address', data.get('NAS-Identifier', None))
return post_auth_fil(data)
elif u"Wireless" in data.get('NAS-Port-Type', ''):
return post_auth_wifi(data)
@radius_event nas_instance = find_nas_from_request(nas).first()
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, vlan_name, reason = decide_vlan(data, True)
mac = data.get('Calling-Station-Id', None) mac = data.get('Calling-Station-Id', None)
log_message = '(wifi) %s -> %s [%s%s]' % \ # Si il s'agit d'un switch
(port, mac, vlan_name, (reason and u': ' + reason).encode('utf-8')) if hasattr(nas_instance, 'switch'):
logger.info(log_message) # 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
# Si NAS ayant des mapping particuliers, à signaler ici log_message = '(fil) %s -> %s [%s%s]' % \
vlan_id = config.vlans[vlan_name] (sw_name + u":" + port, mac, vlan_id, (reason and u': ' + reason).encode('utf-8'))
logger.info(log_message)
# WiFi : Pour l'instant, on ne met pas d'infos de vlans dans la réponse # Filaire
# les bornes wifi ont du mal avec cela
if WIFI_DYN_VLAN:
return (radiusd.RLM_MODULE_UPDATED, return (radiusd.RLM_MODULE_UPDATED,
( (
("Tunnel-Type", "VLAN"), ("Tunnel-Type", "VLAN"),
("Tunnel-Medium-Type", "IEEE-802"), ("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 # Il s'agit d'une borne WiFi
else:
@radius_event return radiusd.RLM_MODULE_OK
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)),
),
()
)
@radius_event @radius_event
def dummy_fun(_): def dummy_fun(_):
@ -235,21 +211,58 @@ def detach(_=None):
print "*** goodbye from auth.py ***" print "*** goodbye from auth.py ***"
return radiusd.RLM_MODULE_OK return radiusd.RLM_MODULE_OK
def find_nas_from_request(nas_id):
def decide_vlan_and_register_macauth(switch_id, port_number, mac_address): if not isinstance(nas_id, int):
# Get port from switch and port number nas = Interface.objects.filter(domain=Domain.objects.filter(name=nas_id))
if not isinstance(switch_id, int):
switch = Switch.objects.filter(switch_interface=Interface.objects.filter(domain=Domain.objects.filter(name=switch_id)))
else: else:
switch = Switch.objects.filter(switch_interface=Interface.objects.filter(ipv4=switch_id)) nas = Interface.objects.filter(ipv4=nas_id)
if not switch: return nas
return ('?', 'Switch inconnu', VLAN_OK)
ipv4 = switch.first().switch_interface.ipv4 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, '')
sw_name = str(switch.first().switch_interface) #ipv4 = nas.ipv4
port = Port.objects.filter(switch=switch.first(), port=port_number) 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_switch(nas, port_number, mac_address):
# Get port from switch and port number
if not nas:
return ('?', 'Nas inconnu', VLAN_OK)
ipv4 = nas.ipv4
sw_name = str(nas)
port = Port.objects.filter(switch=Switch.objects.filter(switch_interface=nas), port=port_number)
if not port: if not port:
return (sw_name, 'Port inconnu', VLAN_OK) 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(): elif not room_user.first().has_access():
return (sw_name, 'Machine inconnue et adhérent non cotisant', VLAN_NOK) return (sw_name, 'Machine inconnue et adhérent non cotisant', VLAN_NOK)
else: else:
result, reason = room_user.first().autoregister_machine(mac_address, ipv4.first()) result, reason = room_user.first().autoregister_machine(mac_address, ipv4)
if result: if result:
return (sw_name, 'Access Ok, Capture de la mac...', VLAN_OK) return (sw_name, 'Access Ok, Capture de la mac...', VLAN_OK)
else: 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 # On gere bien tous les autres états possibles, il ne reste que le VLAN en dur
return (sw_name, 'VLAN impose', int(port.radius)) return (sw_name, 'VLAN impose', int(port.radius))