scripts/gestion/arp.py
bernat 4e225747ce Un peu plus de doc pour le lancer
darcs-hash:20041203173757-d1718-c5169e9538a1dc1763a5d64d1912f7f83a3522fe.gz
2004-12-03 18:37:57 +01:00

97 lines
3.2 KiB
Python
Executable file

#! /usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Serveur SSL qui renvoie la MAC correspondant à une IP
# Ce serveur est utilisé sur Nectaris par les bornes wifi pour faire
# les requêtes ARP.
# Lancement : twistd -n -y arp.py --pidfile=/var/run/arp.pid
# Pas de -n pour qu'il passe en fond
# On utilise twisted
# http://twistedmatrix.com/documents/current/howto/tutorial/intro
from twisted.internet import protocol, reactor, defer, utils
from twisted.internet.ssl import ContextFactory
from twisted.protocols import basic
from twisted.application import internet, service
import sys
sys.path.append('/usr/scripts/gestion')
# LDAP
from ldap_crans import crans_ldap
# Divers
from iptools import AddrInNet
from OpenSSL import SSL
import re
class ServerContextFactory(ContextFactory):
def getContext(self):
"""Création d'un contexte SSL côté serveur."""
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_certificate_file('/etc/ssl/certs/nectaris.pem')
ctx.use_privatekey_file('/etc/ssl/private/nectaris.pem')
return ctx
class ARPProtocol(basic.LineReceiver):
"""Protocole de communication pour récupérer une adresse MAC.
Chaque lignee reçue contient une adresse IP et le serveur répond
avec l'adresse MAC correspondante ou avec `unknown' si celle-ci
est inconnue (ou non autorisée).
"""
def lineReceived(self, IP):
self.factory.getMac(IP
).addErrback(lambda _: "Internal error in server"
).addCallback(lambda m:
(self.answerMac(m)))
def answerMac(self, m):
"""Renvoie au client la bonne adresse MAC.
`m' peut être None.
"""
if m:
return self.transport.write(str(m) + "\r\n")
else:
return self.transport.write("unknown\r\n")
class ARPFactory(protocol.ServerFactory):
"""Backend du serveur. Effectue la résolution IP/MAC."""
protocol = ARPProtocol
def __init__(self, network='0.0.0.0/0'):
self.ldap = crans_ldap()
self.network = network
def getMac(self, IP):
return defer.succeed(self._getMac(IP))
def _getMac(self, IP):
"""Fonction réelle, synchrone, qui obtient l'adresse MAC."""
try:
if AddrInNet(IP, self.network):
results = self.ldap.search('ip=%s' % IP)['machine']
if results:
# On a au moins un résultat, on retourne le premier
return results[0].mac().strip()
else:
# On a rien
return None
else:
# L'IP n'est pas autorisée
return None
except ValueError:
# A priori, ce n'était pas une IP
return None
# Corps du programme
# On écoute sur le port 5243 et on ne répond qu'aux requêtes concernant le
# sous-réseau wifi
application = service.Application('arp')
factory = ARPFactory('138.231.148.0/22')
# Remplacer SSL par TCP pour ne pas utiliser SSL et virer ServerContextFactory
internet.SSLServer(5243, factory,
ServerContextFactory()).setServiceParent(service.IServiceCollection(application))