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

Fix various bugs in auth.py.

This commit is contained in:
Hugo Levy-Falk 2019-09-10 19:11:14 +02:00 committed by chirac
parent 42053ac384
commit f9b7d70314
4 changed files with 36 additions and 49 deletions

View file

@ -117,8 +117,11 @@ def radius_event(fun):
# (str,str) : rlm_python ne digère PAS les unicodes # (str,str) : rlm_python ne digère PAS les unicodes
return fun(data) return fun(data)
except Exception as err: except Exception as err:
exc_type, exc_instance, exc_traceback = sys.exc_info()
formatted_traceback = ''.join(traceback.format_tb(
exc_traceback))
logger.error('Failed %r on data %r' % (err, auth_data)) logger.error('Failed %r on data %r' % (err, auth_data))
logger.debug('Function %r, Traceback: %s' % (fun, repr(traceback.format_stack()))) logger.error('Function %r, Traceback : %r' % (fun, formatted_traceback))
return radiusd.RLM_MODULE_FAIL return radiusd.RLM_MODULE_FAIL
return new_f return new_f
@ -243,7 +246,7 @@ def post_auth(data):
("Tunnel-Type", "VLAN"), ("Tunnel-Type", "VLAN"),
("Tunnel-Medium-Type", "IEEE-802"), ("Tunnel-Medium-Type", "IEEE-802"),
("Tunnel-Private-Group-Id", '%d' % int(vlan_id)), ("Tunnel-Private-Group-Id", '%d' % int(vlan_id)),
) + attributes, ) + tuple(attributes),
() ()
) )
else: else:
@ -256,7 +259,7 @@ def post_auth(data):
return ( return (
radiusd.RLM_MODULE_REJECT, radiusd.RLM_MODULE_REJECT,
attributes, tuple(attributes),
() ()
) )
@ -369,6 +372,10 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
- decision (bool) - decision (bool)
- Attributs supplémentaires (attribut:str, operateur:str, valeur:str) - Attributs supplémentaires (attribut:str, operateur:str, valeur:str)
""" """
attributes_kwargs = {
'client_mac' : str(mac_address),
'switch_port' : str(port_number),
}
# Get port from switch and port number # Get port from switch and port number
extra_log = "" extra_log = ""
# Si le NAS est inconnu, on place sur le vlan defaut # Si le NAS est inconnu, on place sur le vlan defaut
@ -379,14 +386,16 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Nas inconnu', u'Nas inconnu',
RadiusOption.get_cached_value('vlan_decision_ok').vlan_id, RadiusOption.get_cached_value('vlan_decision_ok').vlan_id,
True, True,
RadiusOption.get_attributes('ok_attributes') RadiusOption.get_attributes('ok_attributes', attributes_kwargs)
) )
sw_name = str(getattr(nas_machine, 'short_name', str(nas_machine))) sw_name = str(getattr(nas_machine, 'short_name', str(nas_machine)))
switch = Switch.objects.filter(machine_ptr=nas_machine).first()
attributes_kwargs['switch_ip'] = str(switch.ipv4)
port = (Port.objects port = (Port.objects
.filter( .filter(
switch=Switch.objects.filter(machine_ptr=nas_machine), switch=switch,
port=port_number port=port_number
) )
.first()) .first())
@ -401,7 +410,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Port inconnu', u'Port inconnu',
getattr(RadiusOption.get_cached_value('unknown_port_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('unknown_port_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('unknown_port')!= RadiusOption.REJECT, RadiusOption.get_cached_value('unknown_port')!= RadiusOption.REJECT,
RadiusOption.get_attributes('unknown_port_attributes') RadiusOption.get_attributes('unknown_port_attributes', attributes_kwargs)
) )
# On récupère le profil du port # On récupère le profil du port
@ -415,7 +424,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
attributes = () attributes = ()
else: else:
DECISION_VLAN = RadiusOption.get_cached_value('vlan_decision_ok').vlan_id DECISION_VLAN = RadiusOption.get_cached_value('vlan_decision_ok').vlan_id
attributes = RadiusOption.get_attributes('ok_attributes') attributes = RadiusOption.get_attributes('ok_attributes', attributes_kwargs)
# Si le port est désactivé, on rejette la connexion # Si le port est désactivé, on rejette la connexion
if not port.state: if not port.state:
@ -460,7 +469,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Chambre inconnue', u'Chambre inconnue',
getattr(RadiusOption.get_cached_value('unknown_room_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('unknown_room_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('unknown_room')!= RadiusOption.REJECT, RadiusOption.get_cached_value('unknown_room')!= RadiusOption.REJECT,
RadiusOption.get_attributes('unknown_room_attributes'), RadiusOption.get_attributes('unknown_room_attributes', attributes_kwargs),
) )
room_user = User.objects.filter( room_user = User.objects.filter(
@ -473,7 +482,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Chambre non cotisante', u'Chambre non cotisante',
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT, RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
RadiusOption.get_attributes('non_member_attributes'), RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
) )
for user in room_user: for user in room_user:
if user.is_ban() or user.state != User.STATE_ACTIVE: if user.is_ban() or user.state != User.STATE_ACTIVE:
@ -483,7 +492,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Utilisateur banni ou desactive', u'Utilisateur banni ou desactive',
getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT, RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT,
RadiusOption.get_attributes('banned_attributes'), RadiusOption.get_attributes('banned_attributes', attributes_kwargs),
) )
elif not (user.is_connected() or user.is_whitelisted()): elif not (user.is_connected() or user.is_whitelisted()):
return ( return (
@ -492,7 +501,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Utilisateur non cotisant', u'Utilisateur non cotisant',
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT, RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
RadiusOption.get_attributes('non_member_attributes'), RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
) )
# else: user OK, on passe à la verif MAC # else: user OK, on passe à la verif MAC
@ -516,7 +525,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Machine Inconnue', u'Machine Inconnue',
getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT, RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT,
RadiusOption.get_attributes('unknown_machine_attributes'), RadiusOption.get_attributes('unknown_machine_attributes', attributes_kwargs),
) )
# Sinon on bascule sur la politique définie dans les options # Sinon on bascule sur la politique définie dans les options
# radius. # radius.
@ -527,7 +536,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Machine inconnue', u'Machine inconnue',
getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT, RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT,
RadiusOption.get_attributes('unknown_machine_attributes'), RadiusOption.get_attributes('unknown_machine_attributes', attributes_kwargs),
) )
# L'interface a été trouvée, on vérifie qu'elle est active, # L'interface a été trouvée, on vérifie qu'elle est active,
@ -543,7 +552,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Adherent banni', u'Adherent banni',
getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT, RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT,
RadiusOption.get_attributes('banned_attributes'), RadiusOption.get_attributes('banned_attributes', attributes_kwargs),
) )
if not interface.is_active: if not interface.is_active:
return ( return (
@ -552,7 +561,7 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
u'Machine non active / adherent non cotisant', u'Machine non active / adherent non cotisant',
getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None), getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT, RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT,
RadiusOption.get_attributes('non_member_attributes'), RadiusOption.get_attributes('non_member_attributes', attributes_kwargs),
) )
# Si on choisi de placer les machines sur le vlan # Si on choisi de placer les machines sur le vlan
# correspondant à leur type : # correspondant à leur type :

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.11.23 on 2019-09-09 14:13 # Generated by Django 1.11.23 on 2019-09-10 17:09
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
@ -18,7 +18,6 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('attribute', models.CharField(help_text='See http://freeradius.org/rfc/attributes.html', max_length=255, verbose_name='Attribute')), ('attribute', models.CharField(help_text='See http://freeradius.org/rfc/attributes.html', max_length=255, verbose_name='Attribute')),
('operator', models.CharField(choices=[('=', '='), (':=', ':='), ('==', '=='), ('+=', '+='), ('!=', '!='), ('>', '>'), ('>=', '>='), ('<', '<'), ('<=', '<='), ('=~', '=~'), ('!~', '!~'), ('=*', '=*'), ('!*', '!*')], default=':=', help_text='See https://wiki.freeradius.org/config/Operators', max_length=2, verbose_name='Operator')),
('value', models.CharField(max_length=255, verbose_name='Value')), ('value', models.CharField(max_length=255, verbose_name='Value')),
('comment', models.TextField(blank=True, default='', help_text='Use this field to document this attribute.', verbose_name='Comment')), ('comment', models.TextField(blank=True, default='', help_text='Use this field to document this attribute.', verbose_name='Comment')),
], ],

View file

@ -596,33 +596,11 @@ class RadiusAttribute(RevMixin, AclMixin, models.Model):
verbose_name = _("RADIUS attribute") verbose_name = _("RADIUS attribute")
verbose_name_plural = _("RADIUS attributes") verbose_name_plural = _("RADIUS attributes")
CHOICE_OPERATOR = (
('=' , '=' ),
(':=', ':='),
('==', '=='),
('+=', '+='),
('!=', '!='),
('>' , '>' ),
('>=', '>='),
('<' , '<' ),
('<=', '<='),
('=~', '=~'),
('!~', '!~'),
('=*', '=*'),
('!*', '!*')
)
attribute = models.CharField( attribute = models.CharField(
max_length=255, max_length=255,
verbose_name=_("Attribute"), verbose_name=_("Attribute"),
help_text=_("See http://freeradius.org/rfc/attributes.html"), help_text=_("See http://freeradius.org/rfc/attributes.html"),
) )
operator = models.CharField(
max_length=2,
verbose_name=_("Operator"),
help_text=_("See https://wiki.freeradius.org/config/Operators"),
choices=CHOICE_OPERATOR,
default=':='
)
value = models.CharField( value = models.CharField(
max_length=255, max_length=255,
verbose_name=_("Value") verbose_name=_("Value")
@ -637,8 +615,6 @@ class RadiusAttribute(RevMixin, AclMixin, models.Model):
def __str__(self): def __str__(self):
return ' '.join([self.attribute, self.operator, self.value]) return ' '.join([self.attribute, self.operator, self.value])
def as_tuple(self):
return (self.attribute, self.operator, self.value)
class RadiusOption(AclMixin, PreferencesModel): class RadiusOption(AclMixin, PreferencesModel):
@ -790,9 +766,12 @@ class RadiusOption(AclMixin, PreferencesModel):
) )
@classmethod @classmethod
def get_attributes(cls, name): def get_attributes(cls, name, attribute_kwargs={}):
return ( return (
attribute.as_tuple() (
str(attribute.attribute),
str(attribute.value % attribute_kwargs)
)
for attribute in cls.get_cached_value(name).all() for attribute in cls.get_cached_value(name).all()
) )

View file

@ -400,17 +400,17 @@ class Switch(AclMixin, Machine):
def profile_type_or_nothing(self, profile_type): def profile_type_or_nothing(self, profile_type):
"""Return the profile for a profile_type of this switch """Return the profile for a profile_type of this switch
If exists, returns the defined default profile for a profile type on the dormitory which If exists, returns the defined default profile for a profile type on the dormitory which
the switch belongs the switch belongs
Otherwise, returns the nothing profile""" Otherwise, returns the nothing profile"""
profile_queryset = PortProfile.objects.filter(profil_default=profile_type) profile_queryset = PortProfile.objects.filter(profil_default=profile_type)
if self.get_dormitory: if self.get_dormitory:
port_profile = profile_queryset.filter(on_dormitory=self.get_dormitory).first() or profile_queryset.first() port_profile = profile_queryset.filter(on_dormitory=self.get_dormitory).first() or profile_queryset.first()
else: else:
port_profile = profile_queryset.first() port_profile = profile_queryset.first()
return port_profile or Switch.nothing_profile return port_profile or Switch.nothing_profile()
@cached_property @cached_property
def default_uplink_profile(self): def default_uplink_profile(self):
@ -628,7 +628,7 @@ class Building(AclMixin, RevMixin, models.Model):
@cached_property @cached_property
def cached_name(self): def cached_name(self):
return self.get_name() return self.get_name()
def __str__(self): def __str__(self):
return self.cached_name return self.cached_name
@ -712,7 +712,7 @@ class Port(AclMixin, RevMixin, models.Model):
def get_port_profile(self): def get_port_profile(self):
"""Return the config profil for this port """Return the config profil for this port
:returns: the profile of self (port) :returns: the profile of self (port)
If is defined a custom profile, returns it If is defined a custom profile, returns it
elIf a default profile is defined for its dormitory, returns it elIf a default profile is defined for its dormitory, returns it
Else, returns the global default profil Else, returns the global default profil
@ -730,7 +730,7 @@ class Port(AclMixin, RevMixin, models.Model):
elif self.room: elif self.room:
return self.switch.default_room_profile return self.switch.default_room_profile
else: else:
return Switch.nothing_profile return Switch.nothing_profile()
@classmethod @classmethod
def get_instance(cls, portid, *_args, **kwargs): def get_instance(cls, portid, *_args, **kwargs):