nodemailer / smtp-server

Create custom SMTP servers on the fly
Other
846 stars 145 forks source link

Empty error message on onRcptTo callback #114

Closed cryptouru closed 5 years ago

cryptouru commented 5 years ago

Hello guys,

how are you?

I'm currently trying to return an error when certain conditions are met on the onRcptTo callback and I always get an empty reply when I set the callback to the error I wish to return.

On onMailFrom & onAuth I manage to return the specific error to the client consuming the SMTP server, yet this is not the case for onRcptTo, it just yields an empty result.

Even the snippet from the example does not seem to return an error message:

onRcptTo(address, session, callback) {
        let err;

        if (/^deny/i.test(address.address)) {
            return callback(new Error('Not accepted'));
        }

        // Reject messages larger than 100 bytes to an over-quota user
        if (address.address.toLowerCase() === 'almost-full@example.com' && Number(session.envelope.mailFrom.args.SIZE) > 100) {
            err = new Error('Insufficient channel storage: ' + address.address);
            err.responseCode = 452;
            return callback(err);
        }

        callback();
    },

I believe this may be an issue with the library and not with my particular implementation. Please let me know if theres a workaround or a fix on this.

Regards!

andris9 commented 5 years ago

Are you sure that your SMTP client uses the SIZE extension? Eg. when calling MAIL FROM the expected message size is included like this:

MAIL FROM:<ned@thor.innosoft.com> SIZE=500000

Otherwise the if condition is never true and the error response is never returned.

If you do not use the SIZE extension then do not use session.envelope.mailFrom.args.SIZE

cryptouru commented 5 years ago

Hey @andris9 , thanks for the reply.

The code beforehand is just an actual copy of the example code on this repository, not my actual implementation. I decided to showcase that, as even the code example does not seem to be working.

Regardless of the SIZE extension the following condition can be easily met by sending to deny@something.otherhing

 if (/^deny/i.test(address.address)) {
            return callback(new Error('Not accepted'));
        }

After meting such condition, execution halts before onData (correct behaviour) yet the client gets an empty response instead of the error 'Not accepted'.

I hope this sheds more light on the issue. Let me know if you have any concerns or there is something i'm missing about this.

andris9 commented 5 years ago

It is hard to say what is going on based on this description as the same code has been powering several production environments for years, if its something trivial like non-working RCPT callback then surely it would have emerged a long time ago

cryptouru commented 5 years ago

Is it? Sorry I thought it was quite simple.

when I do:

return callback(new Error('Not accepted')); On the onRcptTo function my SMTP client gets an empty response instead of the error message.

when I do the same on the onMailFrom funtion:

return callback(new Error('From domain not accepted')); the SMTP client gets the error message of 550 with the message of From domain not accepted.

I'm looking for is a solution or a way to also be able to send semantic error messages when a certain condition is met on the onRcptTo callback function.

I also tried to say that I'm concerned this might be I library issue because copying and pasting the example code yielded the same problem described beforehand.

EDIT: Just to clarify, everything is working as expected. When I return error the execution halts, when no error is returned the callback goes by correctly to the next processing function on the server. It's only a matter of getting the error through to the client side

Is it more clear now?

Regards.

andris9 commented 5 years ago

I tested with the example server and it works exactly as expected. If the recipient address starts with deny, it is rejected (and DATA is not allowed), otherwise is is acepted

screen shot 2018-07-10 at 23 06 50

cryptouru commented 5 years ago

Hey @andris9 thank you for your support and your replies. I just tested it using you methodology and got the same result. Maybe my issue was to far fetched and I should have gone into more detail.

I was actually testing this programatically using swift mailer, which is a very well known and supported mailing library. They issue I had was as described on this post:

So even thought the methodology for throwing SMTP errors trough the socket appears to be the same on all cases, on the onRcptTo method that error does not seem to be returned appropriately to some SMTP clients (such as swiftmailer). You may think i'm barking at the wrong tree, yet this library is well supported and been here long enough to make it a good testing case. It also seems to handle appropriately other errors.

So my question is, whats different from onRcptTo method to the others that creates this particular scenario?

Thanks again!

andris9 commented 5 years ago

Could you provide SMTP transaction logs from Swiftmailer? Eg which commanda were sent from the client and what the server responded?

On Thu, 12 Jul 2018 at 17:07, cryptouru notifications@github.com wrote:

Hey @andris9 https://github.com/andris9 thank you for your support and your replies. I just tested it using you methodology and got the same result. Maybe my issue was to far fetched and I should have gone into more detail.

I was actually testing this programatically using swift mailer, which is a very well known and supported mailing library. They issue I had was as described on this post:

  • When I had an auth error swiftmailwer would throw an exception with the returned error from the SMTP server. An error which I would control using the callback.
  • When I tried to send from an unauthorized sender switfmailer would also throw an exception and show my custom error message of unauthorized domain.
  • When I try to send to an unauthorized address (such as deny@something.com) swiftmailer got no error message and just an empty response,

So even thought the methodology for throwing SMTP errors trough the socket appears to be the same on all cases, on the onRcptTo method that error does not seem to be returned appropriately to some SMTP clients (such as swiftmailer). You may think i'm barking at the wrong tree, yet this library is well supported and been here long enough to make it a good testing case. It also seems to handle appropriately other errors.

So my question is, whats different from onRcptTo method to the others that creates this particular scenario?

Thanks again!

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/nodemailer/smtp-server/issues/114#issuecomment-404524653, or mute the thread https://github.com/notifications/unsubscribe-auth/AAIEkgItQQ-alOiXGyTi--qraJceJZTWks5uF1gzgaJpZM4VIQcO .

cryptouru commented 5 years ago

@andris9 thanks for the fast reply! I'll attach here the SMTP log and the different errors and behaviours from swiftmailer for each case.

The second and third cases on my log are what I'm looking to achieve when a to address is rejected.

smtp and switfmailer log.txt

andris9 commented 5 years ago

From the logs it seems that everything works as expected. Swiftmailer returns the number of acepted RCPT TO commands which in your case is 0. Failing MAIL FROM is a hard error, you can't send mail without it. Failing RCPT TO is a soft error, you can provide a list of recipients and some of them might fail, some might succeed.

andris9 commented 5 years ago

Read from Swiftmailer docs how to verify if and which recipients failed and how Swiftmailer actually handles RCPT TO command: https://swiftmailer.symfony.com/docs/sending.html#getting-failures-by-reference

cryptouru commented 5 years ago

@andris9 you are the man! 🥇 Thanks for all the support and time to answer my inquiry.

I totally missed the fact that throwing an exception on such case would make little sense as the SMTP connection might have multiple to addresses to process.

Thanks again for the patience you had 💯

Cheers!