radius: (wip) enregistrement mac <automatique>
Quand une machine se connecte pour la première fois, et qu'elle a une mac auto on enregistre la vraie, et on trigger generate sur komaz.
This commit is contained in:
parent
52f65a152b
commit
e0f16edf28
2 changed files with 75 additions and 19 deletions
|
@ -19,12 +19,14 @@
|
||||||
# Voir des exemples plus complets ici:
|
# Voir des exemples plus complets ici:
|
||||||
# https://github.com/FreeRADIUS/freeradius-server/blob/master/src/modules/rlm_python/
|
# https://github.com/FreeRADIUS/freeradius-server/blob/master/src/modules/rlm_python/
|
||||||
|
|
||||||
from lc_ldap.shortcuts import with_ldap_conn, lc_ldap_anonymous
|
from lc_ldap.shortcuts import with_ldap_conn, lc_ldap_admin
|
||||||
from lc_ldap.crans_utils import escape as escape_ldap
|
from lc_ldap.crans_utils import escape as escape_ldap
|
||||||
|
import lc_ldap.crans_utils
|
||||||
from gestion.config.config import vlans
|
from gestion.config.config import vlans
|
||||||
import lc_ldap.objets
|
import lc_ldap.objets
|
||||||
import radiusd
|
import radiusd
|
||||||
import netaddr
|
import netaddr
|
||||||
|
from gestion.gen_confs.generate import trigger as trigger_generate
|
||||||
|
|
||||||
# Voilà, pour faire marcher le V6Only, il faut se retirer l'ipv4 de sa machine
|
# Voilà, pour faire marcher le V6Only, il faut se retirer l'ipv4 de sa machine
|
||||||
# ou en enregistrer une nouvelle (sans ipv4) avec une autre mac. Moi j'ai la
|
# ou en enregistrer une nouvelle (sans ipv4) avec une autre mac. Moi j'ai la
|
||||||
|
@ -41,6 +43,10 @@ bl_isolement = [u'virus', u'autodisc_virus', u'autodisc_p2p', u'ipv6_ra']
|
||||||
# TODO LOGSSSSS
|
# TODO LOGSSSSS
|
||||||
bl_accueil = [u'carte_etudiant', u'chambre_invalide', u'paiement']
|
bl_accueil = [u'carte_etudiant', u'chambre_invalide', u'paiement']
|
||||||
|
|
||||||
|
# Decorateur utilisé plus tard (same connection)
|
||||||
|
use_ldap = with_ldap_conn(retries=2, delay=5, constructor=lc_ldap_admin)
|
||||||
|
|
||||||
|
@use_ldap
|
||||||
def get_machines(auth_data, conn):
|
def get_machines(auth_data, conn):
|
||||||
mac = None
|
mac = None
|
||||||
username = None
|
username = None
|
||||||
|
@ -49,18 +55,40 @@ def get_machines(auth_data, conn):
|
||||||
# Calling-Station-Id: "une_adresse_mac"
|
# Calling-Station-Id: "une_adresse_mac"
|
||||||
for (key, value) in auth_data:
|
for (key, value) in auth_data:
|
||||||
if key == 'Calling-Station-Id':
|
if key == 'Calling-Station-Id':
|
||||||
mac = escape_ldap(value.decode('ascii', 'ignore').replace('"',''))
|
try:
|
||||||
|
value = value.decode('ascii', 'ignore').replace('"','')
|
||||||
|
mac = lc_ldap.crans_utils.format_mac(value)
|
||||||
|
except:
|
||||||
|
radiusd.radlog(radiusd.L_ERR, 'Cannot format MAC !')
|
||||||
if key == 'User-Name':
|
if key == 'User-Name':
|
||||||
username = escape_ldap(value.decode('ascii', 'ignore').replace('"',''))
|
username = escape_ldap(value.decode('ascii', 'ignore').replace('"',''))
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# format mac (done by preprocess & hints)
|
|
||||||
# format username (strip .wifi.crans.org)
|
# format username (strip .wifi.crans.org)
|
||||||
|
|
||||||
base = u'(objectclass=machine)'
|
base = u'(objectclass=machine)'
|
||||||
# Search by reported mac, then (if failure) search by username (mac or host)
|
|
||||||
return conn.search(u'(&%s(macAddress=%s))' % (base, mac)) or \
|
if mac is None:
|
||||||
conn.search(u'(&%s(|(macAddress=%s)(host=%s.wifi.crans.org)))' %
|
radiusd.radlog(radiusd.L_ERR, 'Cannot read client MAC from AP !')
|
||||||
(base, username, username))
|
return []
|
||||||
|
|
||||||
|
mac = escape_ldap(mac)
|
||||||
|
username = escape_ldap(username)
|
||||||
|
|
||||||
|
search_strats = [
|
||||||
|
# Case 1: Search by mac (reported by AP)
|
||||||
|
u'(&%s(macAddress=%s))' % (base, mac),
|
||||||
|
# Case 2: unregistered mac
|
||||||
|
u'(&%s(macAddress=<automatique>)(host=%s.wifi.crans.org))' %
|
||||||
|
(base, username),
|
||||||
|
]
|
||||||
|
|
||||||
|
for filter_s in search_strats:
|
||||||
|
res = conn.search(filter_s, mode='rw')
|
||||||
|
if res:
|
||||||
|
break
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
def get_prise(auth_data):
|
def get_prise(auth_data):
|
||||||
"""Extrait la prise"""
|
"""Extrait la prise"""
|
||||||
|
@ -91,8 +119,25 @@ def get_prise(auth_data):
|
||||||
if bat_num and bat_name and port:
|
if bat_num and bat_name and port:
|
||||||
return bat_name + "%01d%02d" % (bat_num, port)
|
return bat_name + "%01d%02d" % (bat_num, port)
|
||||||
|
|
||||||
# Decorateur utilisé plus tard (same connection)
|
|
||||||
use_ldap = with_ldap_conn(retries=2, delay=5, constructor=lc_ldap_anonymous)
|
@use_ldap
|
||||||
|
def register_mac(auth_data, machine, conn):
|
||||||
|
for (key, value) in auth_data:
|
||||||
|
if key == 'Calling-Station-Id':
|
||||||
|
try:
|
||||||
|
value = value.decode('ascii', 'ignore').replace('"','')
|
||||||
|
mac = lc_ldap.crans_utils.format_mac(value)
|
||||||
|
except:
|
||||||
|
radiusd.radlog(radiusd.L_ERR, 'Cannot format MAC !')
|
||||||
|
if mac is not None:
|
||||||
|
mac = unicode(mac.lower())
|
||||||
|
machine['macAddress'] = mac
|
||||||
|
machine.history_add(u'auth.py', u'macAddress ( %s )' % mac)
|
||||||
|
machine.save()
|
||||||
|
radiusd.radlog(radiusd.L_INFO, 'Mac set')
|
||||||
|
trigger_generate('komaz', background=True)
|
||||||
|
else:
|
||||||
|
radiusd.radlog(radiusd.L_ERR, 'Cannot find MAC')
|
||||||
|
|
||||||
@use_ldap
|
@use_ldap
|
||||||
def instantiate(p, conn):
|
def instantiate(p, conn):
|
||||||
|
@ -108,15 +153,20 @@ def wifi_authorize(auth_data, conn):
|
||||||
champs login et mot de passe qui serviront ensuite à l'authentification
|
champs login et mot de passe qui serviront ensuite à l'authentification
|
||||||
(MschapV2/PEAP ou MschapV2/TTLS)"""
|
(MschapV2/PEAP ou MschapV2/TTLS)"""
|
||||||
|
|
||||||
items = get_machines(auth_data, conn)
|
items = get_machines(auth_data)
|
||||||
|
|
||||||
if not items:
|
if not items:
|
||||||
radiusd.radlog(radiusd.L_ERR, 'lc_ldap: Nobody found')
|
radiusd.radlog(radiusd.L_ERR, 'lc_ldap: Nobody found')
|
||||||
return radiusd.RLM_MODULE_NOTFOUND
|
return radiusd.RLM_MODULE_NOTFOUND
|
||||||
|
|
||||||
if len(items) > 1:
|
if len(items) > 1:
|
||||||
radiusd.radlog(radiusd.L_ERR, 'lc_ldap: Too many results')
|
radiusd.radlog(radiusd.L_ERR, 'lc_ldap: Too many results (took first)')
|
||||||
|
|
||||||
machine = items[0]
|
machine = items[0]
|
||||||
|
|
||||||
|
if '<automatique>' in machine['macAddress']:
|
||||||
|
register_mac(auth_data, machine)
|
||||||
|
|
||||||
|
|
||||||
proprio = machine.proprio()
|
proprio = machine.proprio()
|
||||||
if isinstance(proprio, lc_ldap.objets.AssociationCrans):
|
if isinstance(proprio, lc_ldap.objets.AssociationCrans):
|
||||||
|
@ -131,8 +181,10 @@ def wifi_authorize(auth_data, conn):
|
||||||
radiusd.radlog(radiusd.L_ERR, 'WiFi authentication but machine has no' +
|
radiusd.radlog(radiusd.L_ERR, 'WiFi authentication but machine has no' +
|
||||||
'password')
|
'password')
|
||||||
return radiusd.RLM_MODULE_REJECT
|
return radiusd.RLM_MODULE_REJECT
|
||||||
|
|
||||||
password = machine['ipsec'][0].value.encode('ascii', 'ignore')
|
password = machine['ipsec'][0].value.encode('ascii', 'ignore')
|
||||||
|
|
||||||
|
# TODO: feed cert here
|
||||||
return (radiusd.RLM_MODULE_UPDATED,
|
return (radiusd.RLM_MODULE_UPDATED,
|
||||||
(),
|
(),
|
||||||
(
|
(
|
||||||
|
@ -150,7 +202,7 @@ def post_auth(auth_data, conn):
|
||||||
reason = ''
|
reason = ''
|
||||||
identity = "" #TODO
|
identity = "" #TODO
|
||||||
prise = "" #TODO
|
prise = "" #TODO
|
||||||
items = get_machines(auth_data, conn)
|
items = get_machines(auth_data)
|
||||||
|
|
||||||
decision = 'adherent',''
|
decision = 'adherent',''
|
||||||
if not items:
|
if not items:
|
||||||
|
@ -162,7 +214,6 @@ def post_auth(auth_data, conn):
|
||||||
if isinstance(machine, lc_ldap.objets.machineWifi):
|
if isinstance(machine, lc_ldap.objets.machineWifi):
|
||||||
decision = 'wifi', ''
|
decision = 'wifi', ''
|
||||||
|
|
||||||
print machine['macAddress'][0].value
|
|
||||||
if not machine['ipHostNumber'] or unicode(machine['macAddress'][0]) in test_v6:
|
if not machine['ipHostNumber'] or unicode(machine['macAddress'][0]) in test_v6:
|
||||||
decision = 'v6only', 'No IPv4'
|
decision = 'v6only', 'No IPv4'
|
||||||
elif machine['ipHostNumber'][0].value in netaddr.IPNetwork('10.2.9.0/24'):
|
elif machine['ipHostNumber'][0].value in netaddr.IPNetwork('10.2.9.0/24'):
|
||||||
|
@ -171,14 +222,14 @@ def post_auth(auth_data, conn):
|
||||||
|
|
||||||
for bl in machine.blacklist_actif():
|
for bl in machine.blacklist_actif():
|
||||||
if bl.value['type'] in bl_isolement:
|
if bl.value['type'] in bl_isolement:
|
||||||
decision = 'isolement', unicode(bl).encode('utf-8')
|
decision = 'isolement', unicode(bl)
|
||||||
if bl.value['type'] in bl_accueil:
|
if bl.value['type'] in bl_accueil:
|
||||||
decision = 'accueil', unicode(bl).encode('utf-8')
|
decision = 'accueil', unicode(bl)
|
||||||
|
|
||||||
vlan_name, reason = decision
|
vlan_name, reason = decision
|
||||||
vlan = vlans[vlan_name]
|
vlan = vlans[vlan_name]
|
||||||
radiusd.radlog(radiusd.L_INFO, 'auth.py: %s -> %s [%s%s]' %
|
radiusd.radlog(radiusd.L_INFO, 'auth.py: %s -> %s [%s%s]' %
|
||||||
(prise, identity, vlan_name, (reason and ': ' + reason))
|
(prise, identity, vlan_name, (reason and u': ' + reason).encode(u'utf-8'))
|
||||||
)
|
)
|
||||||
|
|
||||||
#<!>
|
#<!>
|
||||||
|
@ -198,7 +249,7 @@ def post_auth(auth_data, conn):
|
||||||
# return (0, "Hébergeur non à jour", "accueil")
|
# return (0, "Hébergeur non à jour", "accueil")
|
||||||
#
|
#
|
||||||
#<!>
|
#<!>
|
||||||
|
return radiusd.RLM_MODULE_OK
|
||||||
return (radiusd.RLM_MODULE_UPDATED,
|
return (radiusd.RLM_MODULE_UPDATED,
|
||||||
(
|
(
|
||||||
("Tunnel-Type", "VLAN"),
|
("Tunnel-Type", "VLAN"),
|
||||||
|
|
|
@ -5,12 +5,17 @@ import auth
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2 and False:
|
||||||
print "Give me a mac !"
|
print "Give me a mac !"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Machine à s'authentifier (cerveaulent)
|
# Machine à s'authentifier (cerveaulent)
|
||||||
p=(('Calling-Station-Id', sys.argv[1]),)
|
#p=(('Calling-Station-Id', sys.argv[1]),)
|
||||||
|
|
||||||
|
p=(
|
||||||
|
('Calling-Station-Id', 'ba:27:eb:3c:54:d5'),
|
||||||
|
('User-Name', 'test18'),
|
||||||
|
)
|
||||||
|
|
||||||
print repr(auth.wifi_authorize(p))
|
print repr(auth.wifi_authorize(p))
|
||||||
print "wait for 3s, tu peux aller crasher le serveur pg ou ldap"
|
print "wait for 3s, tu peux aller crasher le serveur pg ou ldap"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue