Implementing POP3

In document in .NET (Page 162-172)

SMTP and POP3: Communicating with email Servers

5.4 Post office protocol 3

5.4.1 Implementing POP3

Like SMTP, POP3 is a command-line-based protocol, where each line is terminated with a line-feed (<enter>) character. For variable length lines, the command is terminated by <enter>.<enter> as in SMTP.

When the server is operating normally, each line will start with +OK. If an error occurs, the line begins with –ERR <some explanation>. Once the client establishes a TCP connection to the server on port 110, the server will always reply with +OK <some greeting message><enter>.

Figure 5.2 SMTP server application.

To access a mailbox, the client must authenticate itself with a username and password. The client sends USER <username><enter>. The server then replies with +OK <welcome><enter>. The password is sent as USER <pass-word><enter> with the same response from the server.

To get summary information about the mailbox, the command

STAT<enter> is issued. To this the server will reply +OK <number of mes-sages> <total size><enter>. Unlike the previous messages, where the text after the +OK could be ignored, here it must be read and stored for future use.

To read back an email, the client sends the RETR <number> command;

Number must be between 1 and the number received in response to the STAT command. The server will respond +OK <some message><enter><mail body><enter>.<enter>. The only piece of important information is the mail body; everything else can be ignored.

To delete emails, the client sends the DELE <number> command. The server will respond +OK <some message><enter>. At this point, it is possi-ble simply to close the TCP connection, but it is recommended to send

QUIT<enter>.

To illustrate the protocol more simply, the following text shows the chain of events that occur between a POP3 server and client. As before, “S”

indicates a transmission from server to client, and “C” indicates a client-to-server transaction. Here, user Bob is checking his emails, when he receives two messages from Alice and Terry.

S: +OK POP3 server ready C: USER bob

S: +OK user valid C: PASS secret S: +OK pass valid C: STAT

S: +OK 2 170 C: RETR 1

S: +OK 120 octets

S: hello, how are you bob?, haven’t seen you in S: ages, any chance you could give me a call S: sometime? I’d love to see you. Alice S: .

C: DELE 1

S: +OK message 1 deleted

C: RETR 2

S: +OK 50 octets

S: Hi bob, I got the order of 500 widgets placed S: with Acme. Terry

S: . C: DELE 2

S: +OK message 2 deleted C: QUIT

S: +OK

This transcript has been simplified for reasons of clarity. Modern mail messages contain headers, including the subject, date, natural names of the sender and recipient, and technical information concerning what software was used to send the email and how it was relayed.

This is a message header sent from fiach_reid@hotmail.com to fiach@eir-com.net.

Return-Path: <fiach_reid@hotmail.com>

Delivered-To: eircom.net-fiach@eircom.net

Received: (vpopmail 31497 invoked by uid 16); 11 Jan 2004 21:51:58 +0000

Received: (qmail 31491 messnum 229855 invoked from

network[64.4.19.76/law12-f76.law12.hotmail.com]); 11 Jan 2004 21:51:57 -0000

Received: from law12-f76.law12.hotmail.com (HELO hotmail.com) (64.4.19.76)

by mail09.svc.cra.dublin.eircom.net (qp 31491) with SMTP;

11 Jan 2004 21:51:57 -0000

Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC;

Sun, 11 Jan 2004 13:51:56 -0800

Received: from 195.92.168.176 by lw12fd.law12.hotmail.msn.com with HTTP;

Sun, 11 Jan 2004 21:51:56 GMT X-Originating-IP: [195.92.168.176]

X-Originating-Email: [fiach_reid@hotmail.com]

X-Sender: fiach_reid@hotmail.com

From: "Fiach Reid" <fiach_reid@hotmail.com>

To: fiach@eircom.net Bcc:

Subject: test message

Date: Sun, 11 Jan 2004 21:51:56 +0000 Mime-Version: 1.0

Status: U X-UIDL:

1073857917.31497.mail09.svc.cra.dublin.eircom.net,S=1118 Content-Type: text/plain; format=flowed

Message-ID: <Law12-F76F1HkikieqX000054e5@hotmail.com>

X-OriginalArrivalTime: 11 Jan 2004 21:51:56.0469 (UTC) FILETIME=[21BF7650:01C3D88D]

Two line-feed characters separate the message header from the body.

Example: POP3 client SPAM filter

SPAM is the term used for mass, unsolicited email. These emails are some-times accompanied by attached viruses, which can be accidentally opened by unwitting users. This application could be used to safely delete emails containing message fragments indicative of a SPAM email; in this case, the string “free money.”

This simple program scans your mailbox for emails containing the text

“free money” and deletes them. This is obviously overly simplistic, but the example is here for illustration, not practicality.

The first step is to draw the user interface; you will need three textboxes, labeled tbServer, tbUsername, and tbPassword. Another textbox is required, named tbStatus; this textbox should be set with multiline to

true. Finally, place a button on the form, and call it btnClean. First, import the required namespaces:

C#

using System.Threading;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.IO;

VB.NET

Imports System.Threading Imports System.Net

Imports System.Net.Sockets Imports System.Text

Imports System.IO

Double-click on the Clean button and type the following code:

C#

private void btnClean_Click(object sender, System.EventArgs e)

{

TcpClient clientSocket = new TcpClient(tbServer.Text,110);

NetworkStream NetStrm = clientSocket.GetStream();

StreamReader RdStrm= new StreamReader(NetStrm);

tbStatus.Text += RdStrm.ReadLine();

sendPOP3cmd("USER "+ tbUsername.Text + "\r\n",NetStrm);

sendPOP3cmd("PASS "+ tbPassword.Text+ "\r\n",NetStrm);

string Data = sendPOP3cmd("STAT\r\n",NetStrm);

string[] BreakDown = Data.Split(" ".ToCharArray());

int messageCount = Convert.ToInt16(BreakDown[1]);

for (int i=1;i<= messageCount;i++) {

StringBuilder message = new StringBuilder("");

Data = "RETR " + Convert.ToString(i) + "\r\n";

byte[] szData=

System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray());

NetStrm.Write(szData,0,szData.Length);

string szTemp = RdStrm.ReadLine();

while(szTemp!=".") {

message.Append(szTemp);

tbStatus.Text += szTemp+"\r\n";

szTemp = RdStrm.ReadLine();

}

if (message.ToString().IndexOf("free money")>0) {

sendPOP3cmd("DELE " + Convert.ToString(i) + "\r\n",NetStrm);

} }

clientSocket.Close();

}

VB.NET

Private Sub btnClean_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles _

btnClean.Click

Dim clientSocket As TcpClient Dim NetStrm As NetworkStream Dim RdStrm As StreamReader Dim Data As String

Dim BreakDown() As String Dim messageCount As Int16 Dim message As StringBuilder Dim szData() As Byte

Dim i As Int16 Dim szTemp As String

clientSocket = New TcpClient(tbServer.Text, 110) NetStrm = clientSocket.GetStream()

RdStrm = New StreamReader(NetStrm) tbStatus.Text += RdStrm.ReadLine()

sendPOP3cmd("USER " + tbUsername.Text + vbCrLf, NetStrm) sendPOP3cmd("PASS " + tbPassword.Text + vbCrLf, NetStrm) Data = sendPOP3cmd("STAT" + vbCrLf, NetStrm)

BreakDown = Data.Split(" ".ToCharArray()) messageCount = Convert.ToInt16(BreakDown(1)) For i = 1 To messageCount

message = New StringBuilder("")

Data = "RETR " + Convert.ToString(i) + vbCrLf szData = _

System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray()) NetStrm.Write(szData, 0, szData.Length)

szTemp = RdStrm.ReadLine() Do While szTemp <> "."

message.Append(szTemp)

tbStatus.Text += szTemp + vbCrLf szTemp = RdStrm.ReadLine() Loop

If message.ToString().IndexOf("free money") > 0 Then sendPOP3cmd("DELE " + Convert.ToString(i) + vbCrLf, _ NetStrm)

End If Next i

clientSocket.Close() End Sub

Note that the sendPOP3cmd function is not yet implemented.

This piece of code uses a different method from the code for the SMTP server to read in lines of data from the network. In this case, the ReadLine

method is used for single-line responses and an iterative loop reads multi-ple-line responses. The chain of events is that the client reads the welcome message from the server, then sends the USER and PASS commands. After it issues the STAT command, the server stores the response in Data.

Data is in the format +OK n1 n2, where n1 is the number of messages and n2 is the total size of the messages. To extract n1 from this string, it is split into an array of strings, delimited by the space character. The second element in this array is now n1.

The program then loops through the messages, issuing the RETR com-mand for each one. The contents of the messages returned are built up using a stringBuilder object, rather than a string, for performance pur-poses. When it reaches a message that has the string “free money” contained within it, it issues the DELE command.

This code implements the sendPOP3cmd function:

C#

public string sendPOP3cmd(string cmd,NetworkStream NetStrm) {

byte[] szData;

string returnedData = "";

StreamReader RdStrm= new StreamReader(NetStrm);

szData =

System.Text.Encoding.ASCII.GetBytes(cmd.ToCharArray());

NetStrm.Write(szData,0,szData.Length);

returnedData = RdStrm.ReadLine();

tbStatus.Text += cmd + "\r\n" + returnedData + "\r\n";

return returnedData;

}

VB.NET

Public Function sendPOP3cmd(ByVal cmd As String, _ ByVal NetStrm As NetworkStream) As String

Dim szData() As Byte Dim returnedData As String Dim RdStrm As StreamReader

RdStrm = New StreamReader(NetStrm) szData = _

System.Text.Encoding.ASCII.GetBytes(cmd.ToCharArray()) NetStrm.Write(szData, 0, szData.Length)

returnedData = RdStrm.ReadLine()

tbStatus.Text += cmd + vbCrLf + returnedData + vbCrLf Return returnedData

End Function

It sends the specified command to the POP3 server and reads back data until it encounters the end-of-line marker \r\n or vbCrLf. The data that is read back is displayed on screen and returned to the calling function.

To test this application, run it from Visual Studio .NET. Type your POP3 server’s IP address into the field provided. You will also need to pro-vide your email account username and password.

Using your email program, send an email to yourself with the words

“free money” in the subject line. Press Send. Now press Clean out. If you scroll the text to the bottom, you will see the POP3 command DELE, signi-fying that the email was deleted as shown in Figure 5.3.

5.5 System.Web.Mail

There is a built-in mechanism for Windows 2000 and later to send emails.

This is called CDOSYS (Microsoft Collaboration Data Objects for

Win-Figure 5.3 POP3 client application.

dows 2000). It is much simpler than implementing SMTP, especially where attachments and rich-text emails are involved; however, CDOSYS can only provide functionality for the client side of the email service.

The following example shows how to send a simple email from source@here.com to destination@there.com via the SMTP server smtp.ntl-world.com (change this to your own SMTP server).

You must first make a reference to System.Web.dll before you can import the System.Web.Mail namespace. This DLL is a .NET assembly, not .COM. To do so, click Project→→→→Add Reference, and then click on the DLL (Figure 5.4).

With that, you can draw your GUI. Drag three textboxes onto the form, name them tbTo, tbFrom, and tbServer. Drag another textbox onto the form, name it tbMessage, and set multiline to true. Finally, place a but-ton on the form, and name it btnSend.

C#

using System.Web.Mail;

Figure 5.4 Visual Studio .NET, Add Reference.

VB.NET

Imports System.Web.Mail

Now click on the Send button and type in the following code:

C#

private void btnSend_Click(object sender, System.EventArgs e) {

MailMessage email = new MailMessage();

email.From = tbFrom.Text;

email.To = tbTo.Text;

email.Subject = "email from .NET";

email.Body = tbMessage.Text;

SmtpMail.SmtpServer = tbServer.Text;

SmtpMail.Send(email);

}

VB.NET

Private Sub btnSend_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSend.Click

Dim email As New MailMessage() With email

.From = tbFrom.Text .To = tbTo.Text

.Subject = "email from .NET"

.Body = tbMessage.Text End With

SmtpMail.SmtpServer = tbServer.Text SmtpMail.Send(email)

End Sub

This code simply sets the various properties of a MailMessage object and passes it to the SmtpMail object. To test the application, run it from Visual Studio .NET. Fill in your own email address in the “To:” field, your SMTP server in the “Server” field, and then fill in whatever you wish in the other fields and press Send. A few moments later, check your email, and you should have received the message (Figure 5.5).

In document in .NET (Page 162-172)