1. Please take a little time for this simple survey! Thank you for participating!
    Dismiss Notice
  2. Dear Pleskians, please read this carefully! New attachments and other rules Thank you!
    Dismiss Notice
  3. Dear Pleskians, I really hope that you will share your opinion in this Special topic for chatter about Plesk in the Clouds. Thank you!
    Dismiss Notice

Resolved Mail-Handler - REJECT with message?

Discussion in 'Plesk Extensions' started by lippoliv, Oct 19, 2016.

  1. lippoliv

    lippoliv Basic Pleskian

    12
    85%
    Joined:
    Dec 18, 2013
    Messages:
    54
    Likes Received:
    2
    Hey there,
    I did register an Mail-Handler (had a view discussions about that here https://talk.plesk.com/threads/extension-dev-handling-mails.338811/) and today morning I played with the "PASS" and "REJECT" output.

    Quickly an question raises: How can I pass a custom Message for the reasen about REJECT the mail into the "Undelivered Mail Returned to Sender" Mail?
    Currently there's just the standard header and the text "Message can't be delivered".

    I tryed the "LOG" but that is just logging, the message dont appear in the mail.

    Code:
    echo "REJECT" >&2
    echo "$originalmail"
    exit 0
    Would be nice to add a message to "REJECT" like it is possible with LOG
    Code:
    # LOG reject reason
    echo "LOG Your spamming to much messages within a timerange of 5 Minutes"
    
    # Write REJECT and reason
    echo "REJECT Your spamming to much messages within a timerange of 5 Minutes"
    Or am I missing the right way to do so?
     
  2. VNick

    VNick Basic Pleskian Staff Member

    7
    60%
    Joined:
    Oct 19, 2016
    Messages:
    59
    Likes Received:
    15
    Location:
    NSK
    Here's a python code snippet to reject with a custom message:

    Code:
    class MailHandler(object):
        HOOK_REJECT  = 3
    
        def exit_reject(self):
            sys.stderr.write("REJECT")
            sys.exit(self.HOOK_REJECT)
    
        def data(self, msg):
            sys.stderr.write("DATA %s\n" % msg)
    
        def reply(self, rcode, xcode, message):
            if not rcode and xcode:
                raise ValueError("rcode should not be empty when xcode is specified")
            r = "REPLY"
            if rcode:
                r += ":" + rcode
            if xcode:
                r += ":" + xcode
            r += " " + message
            self.data(r)
    
        def reject_with_custom_message(self):
            self.reply("554", "5.7.0", "Your message could not be sent. This is a custom message.")
            self.exit_reject()
    
    Hope it's enough to get you started.
     
    lippoliv likes this.
  3. lippoliv

    lippoliv Basic Pleskian

    12
    85%
    Joined:
    Dec 18, 2013
    Messages:
    54
    Likes Received:
    2
    As of I have an Shell-Script I can't use your Code. But I had a look on it and I think that should be possible via Shell too, but I don't get it up.

    Here's the Shell Code:

    Code:
    echo "DATA REPLY: 554: 5.7.1 My Message" >&2
    echo "REJECT" >&2
    
    echo "$msg"
    
    exit 0
    An this is the Output

    Code:
    Oct 22 10:41:13 v22016081573736335 /usr/lib/plesk-9.0/psa-pc-remote[17598]: handlers_stderr: DATA REPLY: 554: 5.7.1 My Message#012REJECT
    Oct 22 10:41:13 v22016081573736335 /usr/lib/plesk-9.0/psa-pc-remote[17598]: REJECT during call 'LWAutomail' handler
    Oct 22 10:41:13 v22016081573736335 /usr/lib/plesk-9.0/psa-pc-remote[17598]: SMTP reply code was not specified by handler
    Oct 22 10:41:13 v22016081573736335 postfix/cleanup[12135]: B971DFF81B: milter-reject: END-OF-MESSAGE from mail.w4.lipperts-web.de[212.83.34.226]: 4.7.1 Service unavailable - try again later; from=<oliver@lipperts-web.de> to=<test@v22016081573736335.megasrv.de> proto=ESMTP helo=<w4.lipperts-web.de>
    
    I dont get any Reply from mailer-daemon at this Point.

    While removing the "DATA" from the first echo i get an Response:

    Code:
    echo "REPLY: 554: 5.7.1 My Message" >&2
    echo "REJECT" >&2
    
    echo "$msg"
    
    exit 0
    Code:
    Oct 22 10:42:44 v22016081573736335 /usr/lib/plesk-9.0/psa-pc-remote[17598]: handlers_stderr: REPLY: 554: 5.7.1 My Message#012REJECT
    Oct 22 10:42:44 v22016081573736335 /usr/lib/plesk-9.0/psa-pc-remote[17598]: REJECT during call 'LWAutomail' handler
    Oct 22 10:42:44 v22016081573736335 postfix/cleanup[12135]: 8FC2AFF81B: milter-reject: END-OF-MESSAGE from mail.w4.lipperts-web.de[212.83.34.226]: 5.7.1 Command rejected; from=<oliver@lipperts-web.de> to=<test@v22016081573736335.megasrv.de> proto=ESMTP helo=<w4.lipperts-web.de>
    
    Code:
    <test@v22016081573736335.megasrv.de>: host
        v22016081573736335.megasrv.de[46.38.233.156] said: 550 5.7.1 Command
        rejected (in reply to end of DATA command)
    
    As you can see ist not "554" and not my message.
    I tryed various ideas, but got nothing running.

    Is this may just possible with an python-script?
     
  4. lippoliv

    lippoliv Basic Pleskian

    12
    85%
    Joined:
    Dec 18, 2013
    Messages:
    54
    Likes Received:
    2
    It would be really nice if I could finish my implementation. Some help from Plesk team would be great.
     
  5. VNick

    VNick Basic Pleskian Staff Member

    7
    60%
    Joined:
    Oct 19, 2016
    Messages:
    59
    Likes Received:
    15
    Location:
    NSK
    @lippoliv, with a little bit of effort it's fairly easy to adapt the provided snippet in Python to any other language. What's important here is the attention to details.

    Here's an example how to add a Bash script as a custom mail handler to reject all mails received by a specific mail address via SMTP with a custom error code and message.

    Code:
    root@a10-52-38-93:~# cat /opt/psa/handlers/hooks/reject-reply
    #!/bin/bash
    
    data()
    {
            echo "DATA $*" >&2
    }
    
    reply()
    {
            local rcode="$1"
            local xcode="$2"
            local message="$3"
    
            data "REPLY${rcode:+:$rcode}${xcode:+:$xcode} $message"
    }
    
    reject()
    {
            echo "REJECT" >&2
            exit 3
    }
    
    reply 554 5.7.1 "My message"
    reject
    root@a10-52-38-93:~# ls -l /opt/psa/handlers/hooks/reject-reply                                                                   
    -rwxr-x--- 1 root popuser 249 Nov 11 10:39 /opt/psa/handlers/hooks/reject-reply
    root@a10-52-38-93:~# plesk sbin mail_handlers_control --add --priority 5 --name reject-msg --mailname mail1@test1.a10-52-38-93.qa.plesk.ru --queue before-queue --type recipient --executable /opt/psa/handlers/hooks/reject-reply --dont-preserve-on-restore --enabled
    root@a10-52-38-93:~# plesk sbin mail_handlers_control --list
    .---.---.-------.--------------------------------------.-----------------.------------------.-----------------.
    | E | P | prior |               address                |       name      |       type       |      queue      |
    |---|---|-------|--------------------------------------|-----------------|------------------|-----------------|
    |   |   |    10 |                                  all |             spf |           global |    before-queue |
    | X |   |    10 |                       all-recipients |     check-quota |           global |    before-queue |
    | X |   |    10 |                       all-recipients |     check-quota |           global | before-sendmail |
    | X |   |    20 | mail1@test1.a10-52-38-93.qa.plesk.ru |           drweb |           sender |   before-remote |
    | X |   |    20 | mail1@test1.a10-52-38-93.qa.plesk.ru |           drweb |        recipient |    before-queue |
    | X |   |     5 | mail1@test1.a10-52-38-93.qa.plesk.ru |      reject-msg |        recipient |    before-queue |
    '---'---'-------'--------------------------------------'-----------------'------------------'-----------------'
    root@a10-52-38-93:~# /opt/psa/handlers/hooks/reject-reply
    DATA REPLY:554:5.7.1 My message
    REJECT
    root@a10-52-38-93:~# echo $?
    3
    root@a10-52-38-93:~# telnet localhost smtp
    Trying ::1...
    Connected to localhost.
    Escape character is '^]'.
    220 a10-52-38-93.qa.plesk.ru ESMTP Postfix (Debian/GNU)
    EHLO localhost
    250-a10-52-38-93.qa.plesk.ru
    250-PIPELINING
    250-SIZE 10240000
    250-ETRN
    250-STARTTLS
    250-AUTH DIGEST-MD5 CRAM-MD5 PLAIN LOGIN
    250-XFORWARD NAME ADDR PROTO HELO SOURCE PORT IDENT
    250-ENHANCEDSTATUSCODES
    250-8BITMIME
    250 DSN
    MAIL FROM: somewhere@example.net
    250 2.1.0 Ok
    RCPT TO: mail1@test1.a10-52-38-93.qa.plesk.ru
    250 2.1.5 Ok
    DATA
    354 End data with <CR><LF>.<CR><LF>
    To: mail1@test1.a10-52-38-93.qa.plesk.ru
    Subject: Test
    
    this is a test message
    .
    554 5.7.1 My message
    QUIT
    221 2.0.0 Bye
    Connection closed by foreign host.
    root@a10-52-38-93:~#
    
    You probably wouldn't want to use --dont-preserve-on-restore above (I used it because I don't care whether this test handler persists over mail restore). Everything else should be fairly close to what you want.
     
    Last edited: Nov 10, 2016
  6. lippoliv

    lippoliv Basic Pleskian

    12
    85%
    Joined:
    Dec 18, 2013
    Messages:
    54
    Likes Received:
    2
    Oh my gosh, the spaces :/

    Thank you. It now works.
     
  7. lippoliv

    lippoliv Basic Pleskian

    12
    85%
    Joined:
    Dec 18, 2013
    Messages:
    54
    Likes Received:
    2
    Is it possible, that the reply is to late in "before-local". It work's in "before-remote" but not in "before-local".
    In both ways the mail got rejected, but my custom message just via rejecting in "before-remote"
     
  8. lippoliv

    lippoliv Basic Pleskian

    12
    85%
    Joined:
    Dec 18, 2013
    Messages:
    54
    Likes Received:
    2
    OK now I'm done I think. But I had to work way other than I thought it would work.

    I used "before-remote" for outgoing Mails, and "before-local" for incoming. Then I mentioned, "before-remote" is called on both (Name is confusing then).
    So I used local IPs the the IP of the senders Domain to figure out if its an incomming or outgoing mail. Worked.
    I still had to use "before-local" because just in this Queue I have the spam-check informations.

    But on "before-local" I just could reject, my custom message won't be give out to the Sender.

    Now I changed my whole Idea. More Tasks to my script, but maybe with an small benefit for me:

    I just act on "before-remote". I ran SpamAssassin manually to the mail I want to check, as of the headers aren't available in this Point. This takes one or two seconds but it should be OK as the Server load is small.

    Benefit: Also for outgoing mails, my SpamAssassin is run and has checked the mail with the same rules as he will do for incomming mails.
    And I'am able to reject with my custom message.
     
  9. VNick

    VNick Basic Pleskian Staff Member

    7
    60%
    Joined:
    Oct 19, 2016
    Messages:
    59
    Likes Received:
    15
    Location:
    NSK
    Yes, in before-local it's too late, since it is executed in the MDA (mail delivery agent) context. Handler needs to be executed in SMTP (or to lesser extent, sendmail) context for REPLY to have any effect.

    There's a SpamAssassin integration in Plesk. Doesn't it suit your needs?
     
Loading...