Demon "ARP" (conversion IP -> MAC) utilisant la base LDAP.
Prevu pour tourner sur Nectaris darcs-hash:20041129225206-d1718-188019d0157929d8525fe95ba5a93b5c528cd971.gz
This commit is contained in:
parent
0c845d0bb4
commit
2b25e74ed3
1 changed files with 93 additions and 0 deletions
93
gestion/arp.py
Executable file
93
gestion/arp.py
Executable file
|
@ -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))
|
Loading…
Add table
Add a link
Reference in a new issue