From 2b25e74ed31f09281a81ce8c7ace3d610309af71 Mon Sep 17 00:00:00 2001 From: bernat Date: Mon, 29 Nov 2004 23:52:06 +0100 Subject: [PATCH] Demon "ARP" (conversion IP -> MAC) utilisant la base LDAP. Prevu pour tourner sur Nectaris darcs-hash:20041129225206-d1718-188019d0157929d8525fe95ba5a93b5c528cd971.gz --- gestion/arp.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100755 gestion/arp.py diff --git a/gestion/arp.py b/gestion/arp.py new file mode 100755 index 00000000..03d14367 --- /dev/null +++ b/gestion/arp.py @@ -0,0 +1,93 @@ +#! /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. + +# 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') +internet.SSLServer(5243, factory, + ServerContextFactory()).setServiceParent(service.IServiceCollection(application))