SMTP example sessions

This article provides an example session using the most basic commands in the Simple Mail Transfer Protocol (SMTP). Our intent is to provide a good feel for how SMTP works, without getting into too much detail. See "Email processes and protocols" for a typical system in which these commands would be used.

Message transfer at each "hop" is done by establishing a TCP connection between a Client SMTP process initiating the transfer and a Server SMTP process receiving the message. After establishing a TCP connection, the message transfer is guided by a sequence of plain-text commands from the Client and reply codes from the Server. The purpose of the commands is to provide "envelope" information so that the message can be handled without having to read its contents. This separation of function allows the email system to work reliably and efficiently, without putting any constraints on the content or syntax of the message itself. The content may even be encrypted, making it totally unintelligible to the mail handling system.

A good way to understand the message transfer process is to send a small message and issue the commands manually using the 'telnet' program available from the command prompt window on most machines. Telnet is a general-purpose program for communication using TCP. Using telnet, you should be able to connect to your email service provider on port 25, the standard email service port (or port 587 if your provider expects you to authenticate your identity).

Here are the steps in a typical message transfer:

1) Establish a TCP connection. 2) Establish a mail session. 3) Provide a Return Address for the next message. 4) Provide a Recipient Address for the next message. 4a) Repeat step 4 for additional recipients. 5) Transfer the message and all its attachments. 5a) Repeat from 3 for additional messages. 6) Terminate the mail session. 7) Close the TCP connection.

and here is what an actual email session looks like (names changed to avoid abuse). $ is the command prompt. C: means Client, and S: means Server:

$ telnet example.org 25 S: 220 example.org ESMTP Sendmail 8.13.1/8.13.1; Wed, 30 Aug 2006 07:36:42 -0400 C: HELO mailout1.phrednet.com S: 250 example.org Hello ip068.subnet71.gci-net.com [216.183.71.68], pleased to meet you C: MAIL FROM: S: 250 2.1.0 ... Sender ok C: RCPT TO: S: 250 2.1.5 ... Recipient ok C: DATA S: 354 Enter mail, end with "." on a line by itself From: Dave\r\nTo: Test Recipient\r\nSubject: SPAM SPAM SPAM\r\n\r\nThis is message 1 from our test script.\r\n.\r\n S: 250 2.0.0 k7TKIBYb024731 Message accepted for delivery C: QUIT S: 221 2.0.0 example.org closing connection Connection closed by foreign host. $

In this session, we have used the five most basic SMTP commands (HELO, MAIL FROM, RCTP TO, DATA, and QUIT) to communicate with a server running Sendmail, one of the most popular mail server programs. The commands and the numerical response codes are standard for all server programs, but the response text following the standard codes may differ. Complete details of these and other less common commands are found in [Klensin08].

Here is a step-by-step explanation of the session above:

1) The telnet program requests a TCP connection to port 25 at the IP address of a server for example.org. Telnet uses a DNS query to find this address.

220 is the standard three-digit reply code for an email server to accept a connection request. If this were an automated process instead of telnet, the Client machine would read the standard code and ignore the rest of the line, which is intended for humans reading a log file. There is no standard form for the information after a reply code. The administrator at example.org might decide, for example, that it is not a good idea to advertise exactly what version of Sendmail he is running. If a vulnerability is discovered in that version, within hours there could be a hundred criminals scanning the Internet for any systems running that version.

2) The HELO command requests a mail session and identifies the Client machine. The identifier should end in the domain name registered to the organization or individual who is responsible for this machine.

250 is the reply code for OK (the command was run without error). Following that code Sendmail provides a more complete greeting message with information (the IPname and IP address of the Client machine) that might be useful to the sender if there is a problem. The IP address is the source address of the TCP connection. The IPname is found by a Reverse DNS query on the IP address.

Notice that the IPname assigned by the Client's network owner can be different than the HELO name used by the Client, so an IPname is not a good way to identify the Client. Network owners often assign thousands of these names using a script which generates the name from the IP address. Savvy mail admins will avoid using these names in their HELO commands, because some anti-spam filters treat these automated names as a sign of spam.

3) The MAIL FROM command provides a Return Address for an error report if there is a problem at any Relay between the sender and the recipient. The Return Address is usually the same as the From Address in the headers of the message, but it can be different.  It might, for example, be re-written by a Forwarder so as to intercept any error reports from downstream agents.  It might also be null, indicating that no error reports should be sent.  This option should always be used for the error messages themselves, avoiding the risk of one error message generating another, ad infinitum.

The 250 reply code is common to four of the commands in this session. Notice there is an additional "enhanced status code" on some of these replies. These enhanced codes were standardized after years of experience using just the original reply codes. They provide a more detailed machine-readable classification of the various replies to a command. Enhanced codes are optional, and all mail servers should work with just the original three-digit codes.

4) The RCPT TO command specifies the address of one recipient. This command is repeated for each recipient.  Any or all of the recipients can be rejected, and delivery will be attempted for those recipients whose address was accepted.  If none are accepted, the entire message is rejected.

One of the functions of an email Relay is to group recipient addresses so that only one copy of a message must be sent to each group at a single destination. This can be a problem if some of those addresses were designated BCC by the message author. SMTP makes no distinction between TO, CC, and BCC addresses. Senders should never assume that BCC addresses are truly hidden.

5) The DATA command initiates the transfer of the message data, which can include headers, plain text, HTML text, and various other blocks of data encoded so that even binary data can be sent as simple strings of ASCII characters. Raw binary data cannot be sent, since there might be confusion if the end-of-line sequence (\r\n) occurs anywhere in the data. Headers come first, terminated by a blank line.  The blank line in our example appears as two consecutive end-of-lines.  The end of the entire message appears as a "." on a line by itself (\r\n.\r\n).

6) The QUIT command terminates the mail session.

7) The TCP connection is then closed by the mail server.