Building a .NET E-mail Application – Part 1

By Remie Bolte


When working with e-mail, two protocols must be addressed. The first protocol sends the message (SMTP), and the second retrieves them from a server (POP3). There is also a third protocol that retrieves the recipient server addresses (DNS; MX records).


The goal of this series is to create an SMTP and POP3 e-mail component for an outlook express look-alike Web-based e-mail application. The component classes will be created in Visual Basic .NET and the e-mail application in ASP.NET (VB .NET).


I will not cover the basics of VB.NET. I assume you have an average knowledge of VB .NET and ASP.NET.


Here is an index for the upcoming articles:



1. SMTP Overview, the RFC explained
2. POP3 Overview, the RFC explained.
3. Create your own SMTP Component
3.1 Component Class structure
3.2 Properties and methods
3.3 TCP Connections
3.4 Internet Message Format RFC
3.5 Creating the message
3.6 Sending the message
3.7 Reviewing the component
4. Create your own POP3 Component
4.1 Component Class structure
4.2 Properties and methods
4.3 TCP Connections
4.4 Processing the received message
4.5 Storing the received message
4.6 Reviewing the component
5. Create your own outlook look-alike application in ASP.NET
5.1 Web site structure
5.2 Use of components
5.3 Using Data
5.4 Making the Web site
5.5 Reviewing the Web site

Although I understand the source code is the most important part of these articles, I will begin this series by explaining the basics of SMTP and POP3. Without this knowledge, it’ll be very difficult to debug the component.


1. SMTP Overview, the RFC Explained




In this article, I will review some basic SMTP Request For Comments (RFC) publications. RFC documents are created by the Internet Engineering Task Force (IETF), which defines the standards of all Internet related protocols. An index of the published RFCs can be found at http://www.ietf.org/rfc.html.


When dealing with the Simple Mail Transfer Protocol, we refer to RFC 2821.

http://www.ietf.org/rfc/rfc2821.txt



1.1 Simple Mail Transfer Protocol (RFC 2821)



RFC 2821 explains the appropriate use of the SMTP protocol. It defines the commands and replies sent by the client or server. Before creating the component, it is important to understand all these commands. Try playing play with them first so you don’t have to debug later on.


You can use Telnet to test the SMTP commands. On windows NT, 2000, XP and .NET (2003) press Start –> Run. Type Telnet and press enter.


The SMTP protocol connects using TCP on default port 25. Most of the SMTP servers don’t allow message relaying so you can only use the server on which your own e-mail address resides. If you have a hotmail address, you can use mx1.hotmail.com as the server.


In telnet, type “Open mx1.hotmail.com 25” (without the quotes)
Now you will be connected to the hotmail SMTP server.

Make the connection with mx1.hotmail.com


Figure 1.1.1 Make the connection with mx1.hotmail.com

Connection made, server waiting for command.


Figure 1.1.2 Connection made, server waiting for command.



1.2 SMTP Commands



The SMTP commands are used to send mail through the server. The necessary commands are listed below, including their syntax and the normal reply code. You can try this in the telnet window. When connected to an SMTP server, the default command order is:



S: 220 myserver.com welcome to the myserver.com SMTP email server
C: “HELO myserver.com” <CRLF>
S: “250 Requested mail action okay, completed”
C: “MAIL FROM: myemail@myserver.com” <CRLF>
S: “250 Requested mail action okay, completed”
C: “RCPT TO: myrecipient@hisserver.com” <CRLF>
S: “250 Requested mail action okay, completed”
C: “DATA” <CRLF>
S: “354 Start mail input; end with <CRLF>.<CRLF>”
C: <Mail Message, see chapter 4.4> <CRLF>.<CRLF>

S: “250 Requested mail action okay, completed”
C: “QUIT” <CRLF>
S: 221 myserver.com service closing transmission channel


There are some commands that can be issued before or during this standard command order. See the details for each command below. The reply message can differ from each server; however, the reply codes cannot. Therefore, when dealing with an SMTP component, we only work with the reply codes. For a detailed description of all the reply codes, see the section “MAIL (FROM)”.


1.2.1 HELO

The HELO command is short for hello; it states a friendly greeting from the client with identification. This command is the first in line after a TCP connection has been established. After the HELO command, the receiving server sets up a reverse-path, forward-path, and mail data buffer to start receiving e-mail data.


Syntax: HELO myserver.com CRLF

Normal Reply Code: 250 Requested mail action okay, completed

Standard Timeout: 5 minutes (After the initial 220 message)


1.2.2 EHLO

The EHLO command is the extended version of the HELO command giving the client the possibility to issue advanced commands. These commands are not used within the SMTP component. More information about the EHLO command can be found in RFC 2821.


1.2.3 MAIL (FROM)

This command is used to specify the source of the message. Here the sender needs to identify itself by giving his/her e-mail address. The SMTP server uses this information to verify if the sender is authorized to send messages. However, the MAIL FROM command isn’t used within the mail message itself. For the recipient to view the sender, the From header must be set in the message data. The MAIL FROM command can only be issued once.


Syntax: MAIL FROM: myemail@myserver.com CRLF

Normal Reply Code: 250 Requested mail action okay, completed

Standard Timeout: 5 minutes


1.2.4 RCPT TO

The Recipient To (RCPT TO) command is used to identify the recipients. This command can be issued more than once and has to be issued for all To, Cc and Bcc recipients. The first action taken by the SMTP server on receiving this command is to verify whether the recipient is a local mailbox. If not, the SMTP server will either throw an error, or, if allowed, try to relay the message. Note that an SMTP server limits the amount of recipients. The RFC standard is 100 recipients per message.


Syntax: RCPT TO: myrecipient@hotmail.com CRLF

Normal Reply Code: 250 Requested mail action okay, completed

Standard Timeout: 5 minutes


1.2.5 DATA

Sending this command means the server will start receiving the actual mail message. The DATA command has 2 parts. The first part is the command with a CRLF. The server then will respond that it is ready to receive the message. After that, the message has to be sent. Information about the message format will be described in the next article. To let the server know when the message is finished, a <CRLF>.<CRLF> has to be sent.(Note that after issuing and executing a DATA command without error [reply code 250], the server accepts responsibility for sending the message or returning a failure message to the sender address as specified in the MAIL command. The process of sending can no longer be aborted within the context of the TCP connection.)



Syntax: DATA CRLF
<message> CRLF.CRLF

Normal Reply Code: 354 Start mail input; end with <CRLF>.<CRLF>
250 Requested mail action okay, completed
Standard Timeout: 2 minutes (DATA Initiation)
3 minutes (Per DATA Block)
10 minutes (After DATA Termination, i.e. 220 reply code)


1.2.6 RSET

The RSET (Reset) command can be used to clear all the SMTP server buffers. It clears all stored data (MAIL FROM, RCPT TO,DATA,HELO), and the server will be ready to restart the sending process. However, if the goal is to start over with the sending of an e-mail, you should issue a HELO command after the reset. (Note that this method is redundant, since issuing a HELO command will also reset the previous data; therefore, a RSET command is unnecessary, but not harmful)


Syntax: RSET CRLF

Normal Reply Code: 250 Requested mail action okay, completed

Standard Timeout: N/A (Server Default)


1.2.7 VRFY

If your goal is to simply verify an e-mail address, use the VRFY command. However, it only verifies whether the e-mail address is a valid local mailbox.



Syntax: VRFY myrecipient@hotmail.com CRLF
Normal Reply Code: 250 “myrecipient@hotmail.com” <myrecipient@>
252 Cannot VRFY user, but will accept message
Standard Timeout: N/A (Server Default)

1.2.8 HELP

Although not always implemented, the HELP command should return a list of commands supported by the SMTP server. When supplying a command name as parameter, the server should return extra information about that command.


Syntax: HELP <command name> CRLF

Normal Reply Code: 214 <Custom Help Information, depends per server>

Standard Timeout: N/A (Server Default)


1.2.9 NOOP

The NOOP command accepts no parameters and can only return a 250 response code. It is implemented only to test the client/server connection. The command can be issued at any time during the session.


Syntax: NOOP CRLF

Normal Reply Code: 250 Requested mail action okay, completed

Standard Timeout: N/A (Server Default)

1.2.10 QUIT

The QUIT command is the opposite to the HELO command; it tells the SMTP server that the client is leaving. In most cases the server will then disconnect the TCP connection. If not it will wait for a new HELO command. The QUIT command also indicates to the server that the client is done transmitting the message, and after issuing this command, the server will start processing any received data.


Syntax: QUIT CRLF

Normal Reply Code: 221 <domain> service closing transmission channel

Standard Timeout: N/A (Connection Closed)


(Note: The RFC recommends SMTP servers to have a default timeout of 5 minutes)



1.3 SMTP Reply Codes



When issuing a command, the server will respond with one of the reply codes listed below. As said before, the text associated with the reply code can differ from each server; however, the syntax of the reply defaults to <Reply Code> <Text> <CRLF>

In case of multiple lines, the syntax of the “text-only” lines is <Reply Code>-<Text> <CRLF>. The last line is that of the default syntax, so the client understands the server is done with the reply.


The reply codes can be divided into five values for the first digit (out of 3):

1xy   Positive Preliminary reply (only for Extended SMTP commands)

2xy   Positive Completion reply (The command has been accepted)

3xy   Positive Intermediate reply (There should be further information [i.e. DATA])

4xy   Transient Negative Completion reply (Command Failed, but can be repeated)

5xy   Permanent Negative Completion reply (Command Failed)


The detailed information of the reply codes is listed below


1.3.1 2xy Reply codes

1.3.1.1 System status, or system help reply (211)

This reply code is followed by information concerning the server, the server status, the server system, or server help.


Reply Code: 211

Issued Command(s): HELP

Standard Timeout: N/A (Server Default)


1.3.1.2 Help message (214)

This reply code is followed by information on how to use the receiver or the meaning of a command. Usually it provides a list of commands accepted by the server.


Reply Code: 214

Issued Command(s): HELP

Standard Timeout: N/A (Server Default)


1.3.1.3 <Domain> Service ready (220)

The 220 reply code is used to confirm connection establishment. It is the primary command after making a TCP connection


Reply Code: 220

Issued Command(s): N/A

Standard Timeout: 5 minutes


1.3.1.4 <Domain> Service Closing Transmission Channel (221)

After issuing the Quit command, the server replies with the 221 code, immediately closing the TCP connection. Therefore, this is the final reply code (unless the connection is terminated before closing the session).


Reply Code: 221

Issued Command(s): QUIT

Standard Timeout: N/A (Connection Closed)


1.3.1.5 Requested mail action okay, completed (250)

This is the most commonly used reply code when a command is accepted and executed without errors. After the 250 reply code the server waits until the next command is issued, or a timeout occurs.


Reply Code: 250

Issued Command(s): HELO, MAIL, RCPT, DATA, RSET, VRFY, NOOP

Standard Timeout: See command description


1.3.1.6 User not local; will forward to <forward-path> (251)

When the server receives a RCPT or VRFY command, it will try to verify the specified user with the local mailboxes. When the user doesn’t exists or has a forward path, the server will reply with the 251 code saying it will accept the user and relay the message.


(Please refer to section 1.3.5 for more information about the 251 and 551 reply codes)


Reply Code: 251

Issued Command(s): RCPT, VRFY

Standard Timeout: 5 Minutes (RCPT command)


1.3.1.7 Cannot VRFY user, but will accept message and attempt delivery (252)

This code works the same as the 251 reply code; however, it will be issued only in response to the VRFY command.


Reply Code: 252

Issued Command(s): VRFY

Standard Timeout: N/A (Server Default)


1.3.2 3xy Reply codes

1.3.2.1 Start mail input; end with <CRLF>.<CRLF> (354)

Issued after the DATA command, the 354 code is used to state that more information is required, and thus the server is waiting for the message body.


Reply Code: 354

Issued Command(s): DATA

Standard Timeout: 2 Minutes (DATA command), 3 Minutes (DATA block), 10 Minutes (DATA Termination)


1.3.3 4xy Reply codes


1.3.3.1 <Domain> Service not available, closing transmission channel (421)

This reply code is given when the server is temporarily unavailable for accepting connections. This would be the case when the server is in the process of shutting down. This code can be replied during the entire client session if unusual circumstances are encountered


Reply Code: 421

Issued Command(s): N/A

Standard Timeout: N/A (Connection Closed)


1.3.3.2 Requested mail action not taken: mailbox unavailable (450)

When a user mailbox is busy because of administrative work (i.e. backup), the 450 reply code is generated when the RCPT command is issued. It states that the message cannot be delivered to that user at this time. The client can repeat the command at a later time.


Reply Code: 450

Issued Command(s): RCPT

Standard Timeout: 5 Minutes (RCPT Command)


1.3.3.3 Requested action aborted: local error in processing (451)

This reply code specifies that an error has occurred while processing the command locally. However, the error is transient, allowing the user to repeat the command after an unspecified period of time.


Reply Code: 451

Issued Command(s): MAIL, RCPT, DATA

Standard Timeout: See command description


1.3.3.4 Requested action not taken: insufficient system storage (452)

The 452 reply code specifies that the SMTP server system has insufficient storage to process the message. Most SMTP server alerts the system administrator when this happens allowing them to solve the problem and thus giving the client the possibility to repeat the command after an unspecified period of time. This reply code can also be issued when there are too many recipients. See the RCPT command for further details.


Reply Code: 452

Issued Command(s): MAIL, RCPT, DATA

Standard Timeout: See command description

1.3.4 5xy Reply codes


1.3.4.1 Syntax error, command unrecognized (500)

This reply code is issued when the SMTP server doesn’t recognize an SMTP command. It can be issued at any time during the client session. Note that all SMTP servers compliant to the RFC accept the standard commands necessary for sending an e-mail (HELO, MAIL, RCPT, DATA, QUIT). The 500 reply code is also issued when the command line is too long


Reply Code: 500

Issued Command(s): All

Standard Timeout: See command description


1.3.4.2 Syntax error in parameters or arguments (501)

When a command is recognized but doesn’t comply to the specified parameters or arguments, the 501 reply code is returned. This reply code can be issued at any time during the client session. In default, it will be returned when the DATA, RSET or QUIT command have parameters or arguments while no EHLO extensions are available.


Reply Code: 501

Issued Command(s): All

Standard Timeout: N/A (Server Default)

1.3.4.3 Command not implemented (502)

The 502 Reply code is related to the 500 command with the only difference that this reply code is issued when the server does recognize the command, but didn’t implement it, so it cannot be executed. Again, the 502 reply code may not be issued when handling the standard commands necessary for sending an e-mail.


Reply Code: 502

Issued Command(s): VRFY, EXPN, HELP

Standard Timeout: N/A (Server Default)


1.3.4.4 Bad sequence of commands (503)

When sending e-mail, a default sequence is specified (as shown in 2.2). Not complying with this sequence can result in the 503 reply code. When this code is returned, the server will wait for a new command, preserving the data already supplied.


Reply Code: 503

Issued Command(s): MAIL, RCPT, DATA

Standard Timeout: See command description


1.3.4.5 Command parameter not implemented (504)

There are a few commands which don’t allow command parameters to be supplied. Ignoring this rule will result in a 504 reply code. Below is a list of commands on which this rule applies.


Reply Code: 504

Issued Command(s): HELO, VRFY, EXPN, HELP

Standard Timeout: N/A (Server Default)


1.3.4.6 Requested action not taken: mailbox unavailable (550)
Although similar to the 450 reply code (1.3.3.2), there is one difference. When the 550 reply code is issued by the server, the mailbox or command is permanently unavailable. With the 450 reply code, the client can repeat the command at a later time. The 550 reply code is issued when a mailbox cannot be found, access is prohibited, or the command is rejected based on security/company policies.

Reply Code: 550

Issued Command(s): HELO, MAIL, RCPT, VRFY, EXPN

Standard Timeout: See command description

1.3.4.7 User not local; please try <forward-path> (551)

Although similar to the 251 reply code (1.3.1.6), the main difference between them is that the server will reject the address when returning a 551 reply code and attempt to deliver the message when returning a 251 reply code.


(Please refer to section 1.3.5 for more information about the 251 and 551 reply codes)


Reply Code: 551

Issued Command(s): RCPT, VRFY

Standard Timeout: See command description


1.3.4.8 Requested mail action aborted: exceeded storage allocation (552)

The 552 reply code is a remaining instance of the 821 RFC published in 1982. In this RFC, the 552 reply code was designed to alert clients exceeding the number of recipients allowed by the server. However, in the 2821 RFC, the 452 reply code became the appropriate command. Since there is a possibility that there are SMTP servers active that were designed on the 821 RFC, clients should treat the 552 reply code as a 452 temporary failure instead of permanently based on the 5xy logic.


Reply Code: 552

Issued Command(s): RCPT

Standard Timeout: 5 Minutes (RCPT command)


1.3.4.9 Requested action not taken: mailbox name not allowed (553)

The 553 reply code is issued when an e-mail address parameter of a command is invalid. This can occur because the syntax of the parameter is invalid or because of security/company policies.


Reply Code: 553

Issued Command(s): MAIL, RCPT, VRFY

Standard Timeout: See command description


1.3.4.10 Transaction failed OR No SMTP service here (554)

When connecting to a SMTP server, the server initiates an SMTP session. In this session the client can issue commands to the server. However, an SMTP server can formally reject an SMTP transaction. If so, the SMTP server will, instead of the normal 220 reply code upon establishing the connection, issue a 554 reply code. The server will maintain the SMTP session until a QUIT command is issued, the connection times out, or the client closed the connection. When receiving a command, with the exception of the QUIT command, after a 554 reply code has been issued, a server will reply with a 503 reply code (1.3.4.4).

Reply Code: 554

Issued Command(s): N/A

Standard Timeout: 5 Minutes


1.3.5 Detailed information about the 251 and 551 reply code

The reason these two reply codes are discussed here is because both deal with the Forward-Path of a mailbox. The Forward-Path can be used by companies or individuals to hide the original address of the user. However, when an SMTP server issues a 251 or 551 reply code, the original address will be revealed. Therefore, most SMTP servers have chosen not to implement these two codes returning a 250 or a 550 reply code instead. If SMTP servers did implement these codes, the server is obliged by the RFC to give users the possibility to disable their use. Also the RFC specifies that the SMTP server SHOULD not expect the client software to update the e-mail address repeating the command. Therefore, implementation of the 251 and 551 reply code within the SMTP client component isn’t necessary.


1.4 Concluding the SMTP Overview



Although I’ve addressed all the commands and reply codes that will be used within the SMTP component, this document cannot truly represent the worth of the 2821 RFC. In it the authors explicitly explain every aspect of the SMTP protocol. View this article as a handy copy during development, but I would recommend everyone to read the RFC to understand the process when creating the SMTP component.


The next part of this article series will be similar to this one. Instead of the SMTP RFC, it will focus on the POP3 RFC. Again, I will review all the necessary commands in order to retrieve e-mail from a POP3 server.


While waiting for that article to be published you can test all the commands listed and to send an email to yourself, your friends, or even a complete stranger, by just using a relatively easy program like telnet.



About the Author



Remie Bolte is a student at communicatiesystemen in the Netherlands. He has experience with C#, VB .NET, VB, ASP, VBScript and SQL. His goal in life is to clean up the Internet and show people how it can benefit their needs. Remie can be reached at r.bolte@vinrem.nl.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read