MailCrab always proceeds `AUTH PLAIN` even though `ENABLE_TLS_AUTH` is not set
cuongvuong-phoenix opened this issue Β· comments
I just discovered the app today, and thanks a lot for this awesome tiny app! The UI looks so nice and clean, and it even has dark mode which is just π.
However, when I'm using it as a replacement for MailCatcher, I cannot receive any email from my app. When launching MailCrab with RUST_LOG=debug
to find the pitfall, I found that the backend always got Sending: 503 Bad sequence of commands
after Received: AUTH PLAIN AAA=
.
When I set ENABLE_TLS_AUTH=true
, my app just hangs and on the backend side of MailCrab nothing is logged after the message Connection from 127.0.0.1:{random port}
(just like when running the curl
command without -k --ssl-reqd
options).
Therefore, I think my app just doesn't have a proper SSL authentication in the development environment, and as MailCrab always proceeds AUTH PLAIN
no matter ENABLE_TLS_AUTH
is set or not, I cannot see any email from my app.
The key thing here is that I'm running MailCatcher/MailCrab mostly in a development environment, so I think it should be better to just ignore the AUTH PLAIN
header, right? Both MailCatcher and MailHog seem to be doing it as they can receive my app emails normally (just that their UI is meh...).
How are you connecting to MailCrab - which SMTP parameters are configured in your app?
Maybe your app tries to upgrade a plain SMTP connection to TLS using STARTTLS, which we do not support (in fact, I want to discourage people from using STARTTLS given the security implications).
In that case you just have to change your SMTP parameters in your app for development.
MailCrab ignores any client authentication, it will accept and proceed any username password, but you can also just omit them in you SMTP parameters.
Thanks for taking a look at this issue.
My app is using Rails 6, and yes, there is a config to use STARTTLS
(enable_starttls_auto: true
in their docs). However, I also initialized a plain new Rails 6 project and used the identical config and MailCrab was receiving the emails very fine.
As I said, the only difference is that somehow my app emails contain a line AUTH PLAIN AAA=
while the plain new Rails project's don't.
My app is quite large already and I'm not sure how to remove that line when sending emails in development environment...
After diving into the MailCrab codebase, I found that the SMTP library maillin
parses the AUTH PLAIN
line and then handles it in the HelloAuth
struct. However, since StateMachine.allow_auth_plain
needs both StateMachine.auth_plain
and StateMachine.tls
to be set correctly (i.e. ENABLE_TLS_AUTH=true
)
=> no pattern is matched within HelloAuth.handle
function
=> default_handler
is called with Cmd::AuthPlain
=> unhandled
is called
=> BAD_SEQUENCE_COMMANDS
response is returned eventually
In the handle_steam
function of MailCrab, even though response.action
is still Action::Reply
, somehow stream
cannot read anything more after processing the line. Not sure whats going on here since stream
is from Tokio and is separated from maillin
...
But the most interesting thing is that when I tried editing the default_handler
function of mailin
to handle Cmd::AuthPlain
just like Cmd::Noop
, everything is working normally and my app emails are received by MailCrab without losing a single bit!
So now I can confirm the root cause is from maillin
, I'm not sure whether I should raise this to the library author or suggest MailCrab to tackle this.
From my point of view:
maillin
is like a standard SMTP server library which means makingAUTH PLAIN
lines becomeNoop
might not be a good idea.- Whereas MailCrab is an email test server, it should be better to just ignore or at least provide an option to ignore the irrelevant lines.
p/s: Just took a look at MailHog and MailCatcher codebase and seems like they don't even process AUTH PLAIN
at all. Not sure if MailCrab should rewrite a custom parser to be more fit within the test environment context tho...
Well, I've just checked again my app configuration, seems like it has some empty env vars (set in .env
) and Ruby is parsing them as empty strings instead of falling to the default case which is nil
. The 3 settings user_name
, password
, and authentication
insert that AUTH PLAIN AAA=
line in the emails which led to the issue I described.
The new Rails project doesn't even have those env vars set, so they're all nil
and no AUTH PLAIN
is inserted. Removing the 3 settings in my app now could easily resolve the problem. βοΈ
However, I still think MailCrab should consider rewriting or modifying the existing parser of maillin
to just completely ignore the authentication thingy because MailCrab is supposed to mostly be used for the test environment.
Anyway, I will just share this beautiful Rust app with my friends and co-workers now. Hope it will grow better π¦
Thank you @cuongvuong-phoenix for your thorough analysis!
You are correct - mailin forbids authentication when TLS is disabled. I will into this a bit further...
As you stated mailin explicitly forbids authentication when TLS is not enabled. This seems reasonable to me, since any credentials would be sent in plaintext if TLS is not enabled. This would be possibly disastrous in a production environment, since credentials could be leaked this way.
MailCrab is intended for a test environment, but not allowing sending encrypted credentials might help users to not make this mistake production. Also in a test setting sending credentials this way would not make much sense.
So for now, MailCrab only supports one of the following:
- SMTP without TLS or authentication
- SMTP over TLS with PLAIN or LOGIN authentication
The LOGIN authentication variant was added to mailin recently, so I will also enable this in MailCrab (see #118)
Thanks again for your deep dive into this issue. I will consider writing a custom SMTP parser in the future.