You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

50 lines
1.6 KiB

  1. import asyncore
  2. import re
  3. from smtpd import SMTPServer
  4. from django.core.management.base import BaseCommand
  5. from hc.api.models import Check
  6. RE_UUID = re.compile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$")
  7. class Listener(SMTPServer):
  8. def __init__(self, localaddr, stdout):
  9. self.stdout = stdout
  10. super(Listener, self).__init__(localaddr, None)
  11. def process_message(self, peer, mailfrom, rcpttos, data, mail_options=None, rcpt_options=None):
  12. to_parts = rcpttos[0].split("@")
  13. code = to_parts[0]
  14. if not RE_UUID.match(code):
  15. self.stdout.write("Not an UUID: %s" % code)
  16. return
  17. try:
  18. check = Check.objects.get(code=code)
  19. except Check.DoesNotExist:
  20. self.stdout.write("Check not found: %s" % code)
  21. return
  22. ua = "Email from %s" % mailfrom
  23. check.ping(peer[0], "email", "", ua, data)
  24. self.stdout.write("Processed ping for %s" % code)
  25. class Command(BaseCommand):
  26. help = "Listen for ping emails"
  27. def add_arguments(self, parser):
  28. parser.add_argument("--host",
  29. help="ip address to listen on, default 0.0.0.0",
  30. default="0.0.0.0")
  31. parser.add_argument('--port',
  32. help="port to listen on, default 25",
  33. type=int,
  34. default=25)
  35. def handle(self, host, port, *args, **options):
  36. listener = Listener((host, port), self.stdout)
  37. print("Starting SMTP listener on %s:%d ..." % (host, port))
  38. asyncore.loop()