#!/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)