I was speaking to a friend the other day about relaying e-mails via a local SMTP server. There was some problem with some code and the e-mails were not going out. In cases like this one of the first things I like to do (especially when you don't get to access the SMTP server directly, but you're relying on some other IT person to set up the relaying permissions correctly) is to manaully connect to the SMTP server and test sending out an e-mail or two.
<sidetrack>The truth is that command-line stuff now days are treated as old-school. Back in the day I grew up in a terminal window. Text and commands are pure love for me. Don't get me wrong, I love the advances made and where we are today as far as the whole computing user-experience goes. I'm not one of those guys that rant about how things were better back in the "good ol' days" or anything. But I am not about to abandon roots and forget how to actually do things via the command line.
</sidetrack> Anyway, something that is useful to know how to do for any developer that ever writes code to send out e-mails is to know how to manually relay mail through an SMTP server.
To make the connection, you'll need to fire up our command-line friend CMD (If you don't know how to start a command window then you're reading the wrong blog, move along). We'll do two things to check that we can sucessfully relay from your current machine to your SMTP server (which might also be your current machine or elsewhere - we're just trying to test that the server will accept relaying from your IP address/machine). First is to check for connectivity between your machine and the server to make sure you're not blocked somewhere along the line. Second is to actually relay an e-mail via the server.
Checking Connectivity with the SMTP Server
An easy way to check connectivity with the server (remember we're staying command-line here) is to use the PORTQRY command-line tool (A free download from Microsoft). You can use portqry to check to make sure that TCP traffic can make it from your machine to the SMTP port 25 on the server. To do so run the following command:
portqry -n MYSERVER -p tcp -e 25
This will query the server to check for connectivity on port/endpoint 25 using the TCP protocol. What you want to hear is "LISTENING". You'll get back 1 of 3 results; listening (A process is listening on the port on the server), not listening (No process is listening on the target port on the server), or filtered (portqry did not receive a response from the port. A process may or may not be listening on the port).
Relaying an E-mail via SMTP
Now on to the fun stuff. Sending the e-mail. On the command-line, open a telnet session.
telnet MYSERVER 25
Just a tip, if you don't see what you type then you need to turn on the local echo by typing (
set local_echo or
set localecho on XP machines). Anyway, make sure you specify port 25 (notice the 25 after the server name).
From here, I'm going to skip the detailed explanations and get to the point. After all, if you're really that interested read the spec. Basically, there are 4 commands you'll need, EHLO or HELO (used by the sending host to identify itself), MAIL FROM (to specify who the mail is from), RCPT TO (to indicate the recipient of the e-mail - this can be repeated multiple times for multiple recipients), and DATA (for the actual text body of the e-mail - you can also specify subject here). One thing to note, whether to use EHLO or HELO for the handshake depends on the capabilities of the SMTP server. All SMTP servers will respond to HELO, older servers might not understand EHLO. The difference between the two is that basically the server's response to EHLO will return additional info about the server's abilities. Also, on the subject of handshakes, to be RFC 2821 compliant, the system name your computer transmits in the EHLO handshake must be identical to the DNS name of the IP address that your computer is currently attached to.
Here's a sample (lines typed by you are in blue, the gray lines are server responses):
220 deathstar.SUPERFREAK.local Microsoft ESMTP MAIL Service, Version: 6.0.2600.2
180 ready at Fri, 6 Jan 2006 16:59:58 -0700
250 deathstar.SUPERFREAK.local Hello [127.0.0.1]
MAIL FROM: email@example.com
250 2.1.0 firstname.lastname@example.org....Sender OK
RCPT TO: email@example.com
250 2.1.5 Administrator@deathstar.SUPERFREAK.local
354 Start mail input; end with <CRLF>.<CRLF>
SUBJECT: This is a test.
Hello, this is just a test.
How are things?
250 2.6.0 <DEATHSTARoqwWADykQv00000001@deathstar.SUPERFREAK.local> Queued mail for delivery
The important thing to note here is the single "." (period) on the last line, followed by a CRLF. This is what tells the server that you're done with your text and to queue for delivery. If the server gives you the following message after typing the
RCPT TO line:
RCPT TO: firstname.lastname@example.org
550 5.7.1 Unable to relay for email@example.com
Then that means that you're not allowed to relay from the machine you are on via the connected SMTP server. Now you can go back to the IT person to let them know that he has not opened up relaying from the machine (IP Address) you're using.
Tip: never open relaying on an SMTP server from everyone. If you must relay on a server then only open relaying from the specific IP address only.
Also, I tend to only use anonymous relaying if it is a specific requirement or need. When possible, always use proper authentication to connect as a user on the server (See how do I authenticate to send an e-mail for details).