| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 | 
							- import subprocess
 - import re
 - 
 - from django.shortcuts import render
 - from django.utils import timezone
 - 
 - from core.models import TLSNotification, TLSLogEntry
 - 
 - 
 - def mailaction(request):
 -     """
 -     This view is called by the sender of an email that was deferred by Postfix
 -     because of missing TLS support of the recipients mail server.
 -     It redirects or deletes the email.
 -     The view expects URL parameters:
 -     # /?id=06DA1A40B9B&action=redirect
 -     or
 -     # /?id=06DA1A40B9B&action=delete
 -     """
 - 
 -     ######################################################
 -     # Get parameters from url
 -     try:
 -         queue_id = request.GET.get('queue_id', '')
 -         action = request.GET.get('action', '')
 -     except:
 -         queue_id = ""
 -         action = ""
 - 
 -     # Show the frontpage if no parameters are given in URL
 -     if queue_id == "" or action == "":
 -         return render(request,
 -                       'core/frontpage.html',
 -                       {"reason": "no parameters"})
 - 
 -     ######################################################
 -     # Raise an error if the mail with the given queue id is not
 -     # existent in the queue on the postfix server
 -     p = subprocess.Popen(['sudo', 'postcat', '-qh', queue_id],
 -                          stdin=subprocess.PIPE,
 -                          stdout=subprocess.PIPE,
 -                          stderr=subprocess.STDOUT)
 -     output = str(p.stdout.read(), "utf-8")
 - 
 -     if "No such file or directory" in output:
 -         return render(request,
 -                       'core/error.html',
 -                       {"queue_id": queue_id,
 -                        "output": output, })
 - 
 -     ######################################################
 -     # SEND MAIL UNENCRYPTED
 -     if action == "redirect":
 - 
 -         ##########################################################################
 -         # Put mail in hold queue so that Postfix does not start another
 -         # attempt to deliver it.
 -         p = subprocess.Popen(['sudo', 'postsuper', '-h', queue_id],
 -                              stdin=subprocess.PIPE,
 -                              stdout=subprocess.PIPE,
 -                              stderr=subprocess.STDOUT)
 -         output = str(p.stdout.read(), "utf-8")
 - 
 -         ##########################################################################
 -         # Get envelope information
 -         # We need:
 -         # - the sender: see below, if we do not pass the sender to sendmail, it sets
 -         #               "root@mail.domain.com" as the envelope sender. This is
 -         #               not what we want.
 -         # - the recipients: we do want to send the mail not to all recipients mentioned
 -         #                   in the header. The mail was already sent to most of the
 -         #                   recipients. We just want so send the mail to those recipients
 -         #                   who did not already get the email since there were errors so
 -         #                   the mail was not delivered. These are the recipient lines in
 -         #                   the envelope!
 - 
 -         # Get the envelope for queue_id and grep the line with "recipient:" and "sender:"
 -         # TODO: Use Python, not egrep!
 -         p1 = subprocess.Popen(['sudo', 'postcat', '-qe', queue_id], stdout=subprocess.PIPE)
 -         p2 = subprocess.Popen(['egrep', '^recipient:|sender:'], stdin=p1.stdout, stdout=subprocess.PIPE)
 -         p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
 -         envelope = p2.communicate()[0]
 - 
 -         # extract recipient and sender addresses
 -         recipients = ""
 -         for line in envelope.decode("utf-8").split('\n'):
 -             if line is not "":  # there is an empty line at the end after splitting, so make sure it is ignored
 -                 if "recipient:" in line:
 -                     recipients += re.search('recipient:.(.*)', line).group(1) + " "
 -                 elif "sender:" in line:
 -                     envelope_sender = re.search('sender:.(.*)', line).group(1)
 - 
 -         ##########################################################################
 -         # redirect mail to second mail server instance
 -         #
 -         # Information about the used sendmail options:
 -         #
 -         # -t option extracts recipients from message header. This is *not* what we want!
 -         #    The mail is already sent to recipients with no errors. We just want to send
 -         #    the mail to the recipients that had errors. These are mentioned in the
 -         #    "recipient" lines of the envelope. So we collected them in the variable
 -         #    "recipients" and pass them to sendmail.
 -         #
 -         # -C send mail to specified postfix instance (second postfix instance with opp. TLS)
 -         #
 -         # -f option sets the envelope sender.
 -         #
 -         # If we do not set the envelope sender, we get this:
 -         #
 -         # Received: from [XXX.XXX.XXX.XXX] (helo=mail.domain.com)
 -         #   by mail2.domain.com with esmtp (Exim 4.84)
 -         #   (envelope-from <root@mail.domain.com>)
 -         #   id 1a9pFz-0006zY-0r
 -         #   for user@domain.com; Fri, 18 Dec 2015 08:15:15 +0100
 -         #
 -         # but we want to have this:
 -         #
 -         # Received: from [XXX.XXX.XXX.XXX] (helo=mail.domain.com)
 -         #   by mail2.domain.com with esmtp (Exim 4.84)
 -         #   (envelope-from <mailbox@suenkler.info>)
 -         #   id 1a9pD5-00014n-PX
 -         #   for user@domain.com; Fri, 18 Dec 2015 08:12:16 +0100
 -         #
 -         # TODO: Make sure, the sendmail command is correct!
 -         #       Depending on the environment it could be necessary to set -F (sender full name)
 -         #       to an empty string.
 -         p1 = subprocess.Popen(['sudo', 'postcat', '-qbh', queue_id],
 -                               stdout=subprocess.PIPE)
 -         p2 = subprocess.Popen(['sendmail', '-C', '/etc/postfix-out/', '-f', envelope_sender, recipients],
 -                               stdin=p1.stdout,
 -                               stdout=subprocess.PIPE)
 -         p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
 -         output = p2.communicate()[0].decode("utf-8")
 - 
 -         ##########################################################################
 -         # now delete mail from queue
 -         p = subprocess.Popen(['sudo', 'postsuper', '-d', queue_id],
 -                              stdin=subprocess.PIPE,
 -                              stdout=subprocess.PIPE,
 -                              stderr=subprocess.STDOUT)
 -         output += str(p.stdout.read(), "utf-8")
 - 
 -         # Create log entry in database
 -         q = TLSLogEntry(queue_id=queue_id,
 -                         sender=envelope_sender,
 -                         action=action,
 -                         recipients=recipients,
 -                         date=timezone.now())
 -         q.save()
 - 
 -     ######################################################
 -     # DELETE MAIL
 -     elif action == "delete":
 -         ##########################################################################
 -         # Delete mail from queue
 -         p = subprocess.Popen(['sudo', 'postsuper', '-d', queue_id],
 -                              stdin=subprocess.PIPE,
 -                              stdout=subprocess.PIPE,
 -                              stderr=subprocess.STDOUT)
 -         output = str(p.stdout.read(), "utf-8")
 - 
 -     ################################################################################
 -     # The mail is now deleted or redirected, so we can delete the database entry
 -     # of the last notification
 -     try:
 -         notification = TLSNotification.objects.get(queue_id=queue_id)
 -     except:
 -         notification = ""
 - 
 -     if notification:
 -         notification.delete()
 - 
 -     #######################################################
 -     # Return Success Page
 -     return render(request,
 -                   'core/mailaction.html',
 -                   {"queue_id": queue_id,
 -                    "action": action,
 -                    "output": output, })
 
 
  |