In practice, for submission connections, servers will accept anything that is syntactically valid [in EHLO domain], because in practice, most SMTP submission clients nowadays can't really send anything particularly meaningful anyway (end user devices usually don't have DNS names, and often are behind NAT and thus at best know their RFC1918 address on the random LAN that the happen to be connected to).
Yes, the RFC mandates that SMTP servers don't reject messages just because they don't like the EHLO command, but practice trumps RFC.
But, for a local IoT server implementing a mail transfer agent, forwarding the messages to the appropriate mail servers, it really should verify the client IP address matches the local address, the
EHLO domain is either that same IP address or a matching domain name that matches the filter set in e.g. Exim
auth_advertise_hosts, or otherwise your IoT server may be exploitable to forward spam by the ton because the IoT appliances source code revealed the username and password.
I've mostly been on the other side of this, configuring mail transfer agents on servers, so I definitely "err" on the safe side here. You
do not want your IoT device firmware to reveal how to use the related SMTP servers as spam relays; trust me on this.
Hmm.. for a better
EHLO advice, I think using either the configured (host and) domain name, or the IP address if unknown or not configured, would work best. This way, if the mail provider requires something here, the user can configure their IoT box to comply.
For one, technically, you would first have to check in the EHLO response which authentication mechanisms are supported. Of course, if you only support one anyway, I guess you might as well just try that one.
But also, LOGIN is obsoleted, and the non-obsolete plain-text mechanism, PLAIN, makes things quite a bit simpler, because you send username and password in one auth string, which then also can be supplied as the initial-response in the AUTH command itself, so there is no need to handle the command continuation.
Fully agreed.
I guess it should be noted that if a line of the message body starts with a '.', then you have to double that to '..', or else your mail might get corrupted (and, depending on the circumstances, you might have a security problem).
Yep, true.
I guess a better suggestion for sending email from an IoT device would be:
- Connect to the SMTP server using the appropriate port, and wait for a response. The response should be 220.
- Send "EHLO client\r\n", and wait for a response. The response should be 220.
The response text contains "AUTH" followed by whitespace-separated authentication methods, which should include "PLAIN". - Send "AUTH PLAIN creds\r\n", and wait for a response. The response should be 235.
Try not to hardcode creds in your firmware, and instead treat it as a (privileged) configuration string. - Send "MAIL FROM:<sender>\r\n", and wait for a response. The response should be 250.
- Send "RCPT TO:<recipient>\r\n", and wait for a response. The response should be 250.
- Send "DATA\r\n", and wait for a response. The response should be 354.
- Send each header line, for example "Subject: This is the message subject\r\n". (Every header line must end with "\r\n".)
- Send empty line between headers and message body, "\r\n".
- Send message body. If a line begins with a ., it should be doubled (to ..). If the body is not empty, it must end with "\r\n".
- Send ".\r\n", and wait for a response. The response should be 250.
- Send "QUIT\r\n", and wait for a response. The response should be 221.
where
host is the fully-qualified host name if configured, or the IP address if not configured;
creds is Base64 encoded username followed by an ASCII null character followed by the password;
sender is the sender mail address matching
creds (and
host if the SMTP server does strict EHLO checking); and
recipient is the recipient mail address.
RFC 5322 describes message headers you can use, and how those headers and body can be formatted.