Le serveur gitlab sera inaccessible le mercredi 19 février 2020 de 13h à 14h pour une intervention de maintenance programmée.

...
 
Commits (3)
......@@ -39,6 +39,7 @@ import os
import sys
import logging
import radiusd # Module magique freeradius (radiusd.py is dummy)
import json
from django.core.wsgi import get_wsgi_application
from django.db.models import Q
......@@ -68,6 +69,7 @@ RADIUS_POLICY = options.radius_general_policy
#: Serveur radius de test (pas la prod)
TEST_SERVER = bool(os.getenv('DBG_FREERADIUS', False))
LEGACY_WIFI_PASSWORDS = json.load(open('/etc/freeradius/3.0/wifi_passwords', 'r'))
# Logging
class RadiusdHandler(logging.Handler):
......@@ -156,6 +158,34 @@ def authorize(data):
user = data.get('User-Name', '').decode('utf-8', errors='replace')
user = user.split('@', 1)[0]
mac = data.get('Calling-Station-Id', '')
#### Legacy, anciens login/mdp des machines
if user in LEGACY_WIFI_PASSWORDS:
logger.info(u"Legacy auth for login %s" % user.encode('utf-8'))
interface = Interface.objects.filter(domain__name=user, mac_address=mac).first()
if not interface:
logger.info(u"Rejet, Interface introuvable, mac et user login differents")
return radiusd.RLM_MODULE_REJECT
if not interface.is_active:
logger.info(u"Rejet, interface desactivee")
return radiusd.RLM_MODULE_REJECT
user_object = interface.machine.user
if not user_object.has_access():
logger.info(u"Adherent non connecte/cotisant")
return radiusd.RLM_MODULE_REJECT
return (
radiusd.RLM_MODULE_UPDATED,
(),
(
(str("Cleartext-Password"), str(LEGACY_WIFI_PASSWORDS[user])),
),
)
result, log, password = check_user_machine_and_register(
nas_type,
user,
......
......@@ -110,3 +110,6 @@ GID_RANGES = {
# Some Django apps you want to add in you local project
OPTIONNAL_APPS = ()
CAPTIVE_IP_RANGE = "10.51.0.0/16"
{% extends "users/sidebar.html" %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2017 Gabriel Détraz
Copyright © 2017 Goulven Kermarec
Copyright © 2017 Augustin Lemesle
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
{% endcomment %}
{% load bootstrap3 %}
{% load static %}
{% block title %}Machine non reconnue{% endblock %}
{% block content %}
<div class="alert alert-success">
<h4 class="alert-heading">Création d'une machine fillaire</h4>
<p>Pour créer une machine fillaire, connectez vous puis débranchez et rebranchez votre cable Ethernet</p>
</div>
{% bootstrap_form_errors loginform %}
<form class="form" method="post">
{% csrf_token %}
{% bootstrap_form loginform %}
<button type="submit" class="btn btn-success">Login</button>
</form>
{% if success %}
Votre Machine a été enregistré avec succès, débranchez votre cable, attendez quelques secondes puis rebranchez le, vous devriez alors avoir internet ! (si vous êtes à jour de cotisation).
{% endif %}
{% endblock %}
......@@ -48,7 +48,7 @@ from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth import views as auth_views
from .views import index, about_page, contact_page
from .views import index, about_page, contact_page, portail_login
handler500 = 're2o.views.handler500'
handler404 = 're2o.views.handler404'
......@@ -58,6 +58,7 @@ urlpatterns = [
url(r'^about/$', about_page, name='about'),
url(r'^contact/$', contact_page, name='contact'),
url('^logout/', auth_views.logout, {'next_page': '/'}),
url(r'^portail_login/$', portail_login, name='portail_login'),
url('^', include('django.contrib.auth.urls')),
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^admin/', include(admin.site.urls)),
......
......@@ -34,6 +34,11 @@ from django.template.context_processors import csrf
from django.conf import settings
from django.utils.translation import ugettext as _
from django.views.decorators.cache import cache_page
from django.contrib.auth.forms import AuthenticationForm
from django.contrib import messages
import subprocess
import ipaddress
from preferences.models import (
Service,
......@@ -41,9 +46,10 @@ from preferences.models import (
AssoOption,
HomeOption
)
from machines.models import Nas
from .contributors import CONTRIBUTORS
from re2o.settings import CAPTIVE_IP_RANGE
def form(ctx, template, request):
"""Form générique, raccourci importé par les fonctions views du site"""
......@@ -69,6 +75,60 @@ def index(request):
'asso_name': asso_name
}, 're2o/index.html', request)
def get_ip(request):
"""Returns the IP of the request, accounting for the possibility of being
behind a proxy.
"""
ip = request.META.get("HTTP_X_FORWARDED_FOR", None)
if ip:
# X_FORWARDED_FOR returns client1, proxy1, proxy2,...
ip = ip.split(", ")[0]
else:
ip = request.META.get("REMOTE_ADDR", "")
return ip
def apply(cmd):
return subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
def mac_from_ip(ip):
cmd = ['/usr/sbin/arp','-na',ip]
p = apply(cmd)
output, errors = p.communicate()
if output is not None :
mac_addr = output.decode().split()[3]
return str(mac_addr)
else:
return None
def portail_login(request):
""" Check for authentication. If success, register the current machine for the user."""
login_form = AuthenticationForm(data=request.POST or None)
success = False
if login_form.is_valid():
remote_ip = get_ip(request)
if ipaddress.ip_address(remote_ip) in ipaddress.ip_network(CAPTIVE_IP_RANGE):
mac_addr = mac_from_ip(remote_ip)
if mac_addr:
nas_type = Nas.objects.get(name="Switches")
result, reason = login_form.user_cache.autoregister_machine(mac_addr, nas_type)
if result:
success=True
else:
messages.error(request, "Erreur dans l'enregistrement de la machine : %s" % reason, '')
else:
messages.error(request, "Erreur dans la récupération de la MAC")
else:
messages.error(request, "Merci de vous connecter en filaire pour enregistrer une machine")
return form(
{
'loginform': login_form,
'success' : success
},
're2o/portail_login.html',
request
)
@cache_page(7 * 24 * 60 * 60)
def about_page(request):
......