mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-22 03:13:12 +00:00
Fix various bugs in auth.py.
This commit is contained in:
parent
42053ac384
commit
f9b7d70314
4 changed files with 36 additions and 49 deletions
|
@ -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 :
|
||||||
|
|
|
@ -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')),
|
||||||
],
|
],
|
|
@ -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()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in a new issue