
Celui-ci écoute au travers d'une socket unix. Il permet ainsi de garder une connexion ldap (et pg et cie) en permanence ouverte. Ce qui accélère le traitement des rapports de arpwatch. Pour utiliser ce server, report.py (ancien arpwatch_sendmail.py) tente de se connecter à cette socket et envoie le mail lui-même en cas d'échec. On rajoute également un initscript pour arpwatch_sendmail_server. Il n'est pas parfait et si vous aimez pas, feel free to edit.
96 lines
3 KiB
Python
Executable file
96 lines
3 KiB
Python
Executable file
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Ajout d'un whos et d'un tracage aux mails d'arpwatch
|
|
# Auteurs : Stéphane Glondu, Cyril Cohen, Daniel STAN, Valentin Samir
|
|
# Licence : GPLv2
|
|
|
|
from __future__ import print_function
|
|
|
|
import sys, os, re
|
|
import socket
|
|
|
|
import common
|
|
|
|
sys.path.append('/usr/scripts')
|
|
from gestion.tools.locate_mac import trace_machine, format_mac, info_machine
|
|
from gestion.config import NETs
|
|
from gestion.iptools import AddrInNets
|
|
from utils.sendmail import sendmail
|
|
|
|
# On récupère les destinataires dans les arguments (très ad hoc)
|
|
recipients = [ mail for mail in sys.argv[1:] if '@' in mail ]
|
|
if not recipients:
|
|
print("Pas de mail fourni: affichage sur stdout.",
|
|
file=sys.stderr)
|
|
|
|
find_mac = re.compile(r'[0-9A-Fa-f]{1,2}(?::[0-9A-Fa-f]{1,2}){5}')
|
|
find_ip = re.compile(r'[0-9]{1,3}(?:\.[0-9]{1,3}){3}')
|
|
arpwatched_net = NETs['all'] + NETs['adm'] + NETs['accueil'] + NETs['isolement'] + NETs['personnel-ens'] + NETs['evenementiel']
|
|
|
|
def get_machine(unformated_mac):
|
|
"""Renvoie les informations sur la machine à partir de sa mac"""
|
|
mac = format_mac(unformated_mac)
|
|
return u"\n" + info_machine(mac) + u"\n" + trace_machine(mac)
|
|
|
|
def get_subject(headers_list):
|
|
for line in headers_list:
|
|
if line.lower().startswith('subject:'):
|
|
return line[9:].strip()
|
|
return None
|
|
|
|
def report(texte, fallback=False):
|
|
"""Envoi d'un rapport"""
|
|
textes = texte.splitlines(True)
|
|
try:
|
|
i = textes.index('\n')
|
|
except ValueError:
|
|
print("wrong formatted mail", file=sys.stderr)
|
|
return
|
|
|
|
headers = textes[:i]
|
|
textes = textes[(i+1):]
|
|
|
|
# Extrait le sujet
|
|
subject = get_subject(headers)
|
|
|
|
# Cherche les IP dans le corps
|
|
try:
|
|
ip = set(find_ip.findall(texte)).pop()
|
|
except KeyError:
|
|
ip = None
|
|
# On complète le message
|
|
if u'flip flop' in subject and ip is not None and AddrInNets(ip, arpwatched_net):
|
|
try:
|
|
macs = find_mac.findall(texte)
|
|
for mac in macs:
|
|
textes.append(get_machine(mac))
|
|
except:
|
|
# En cas d'exception, on envoie le traceback
|
|
import traceback
|
|
textes.append(u'\n')
|
|
textes.append(u''.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)))
|
|
if fallback:
|
|
textes.append(u'\nAttention, arpwatch/sendmail_server.py inactif !\n')
|
|
textes.append(u'\n-- \narpwatch_sendmail.py\n')
|
|
|
|
out = ''.join(textes)
|
|
if recipients:
|
|
sendmail(u"arpwatch@crans.org", recipients, subject, out,
|
|
more_headers = {
|
|
'X-Mailer': __file__,
|
|
})
|
|
else:
|
|
print(out)
|
|
|
|
if __name__ == '__main__':
|
|
data = sys.stdin.read()
|
|
# On essaye d'envoyer le mail à la socket de sendmail_server
|
|
# et au pire, on envoie nous-même le mail
|
|
try:
|
|
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
s.connect(common.SOCKET_FILE)
|
|
s.send(data)
|
|
s.close()
|
|
except socket.error:
|
|
report(data, fallback=True)
|