POP3 Server Authentication

Receive Email Walkthrough: for C# and VB NET Students

 

After the handshake code from the previous lesson, we can now try a username and password.

The PopCommand function you have just written will deal with all the commands we send to the POP3 server, and the responses we get back. As was mentioned, the data you send and the data you get back is in Octets (bytes). So we first need to convert the command string we're sending to the server into an array of bytes. In the Try part of a Try … Catch block, add these two lines to your PopCommand function:

VB Net

serverCommand = serverCommand & vbCrLf

Dim serverBytes( ) As Byte = Encoding.ASCII.GetBytes( serverCommand )

C#

serverCommand = serverCommand + "\r\n";

Byte[] serverBytes = Encoding.ASCII.GetBytes(serverCommand);

The first line just adds a linefeed character to the end of the command we're going to send. The second line sets up a Byte array.

We've called this array serverBytes. After an equal sign, we have this:

Encoding.ASCII.GetBytes( serverCommand )

This part encodes ASCII characters. It converts the text that's in the variable serverCommand and turns each character into bytes for the array. The first of the server commands we're going to send is USER your_username. Instead of it being in text, however, the above lines will turn them into bytes. The server won't be able to read the text, if you don't.

We can set up a new StreamReader and a string variable next, to deal with the response we get back from the server. Add these two lines:

VB Net

Dim readStreamBytes As StreamReader
Dim serverResponse As String

C#

StreamReader readStreamBytes;
String serverResponse;

Now add the following rather tricky four lines:

VB Net

networkStream.Write( serverBytes, 0, serverBytes.Length )
readStreamBytes = New StreamReader( networkStream )
serverResponse = readStreamBytes.ReadLine( )

Return serverResponse

C#

networkStream.Write(serverBytes, 0, serverBytes.Length);
readStreamBytes = new StreamReader(networkStream);
serverResponse = readStreamBytes.ReadLine();

return serverResponse;

The NetworkStream object we set up will be dealing with the commands we send to the server:

networkStream.Write( serverBytes, 0, serverBytes.Length )

In between the round brackets of Write, we have 3 values. The first one is the array of Bytes. But we're actually writing to a Buffer (an area of memory). The location in the Buffer that we want to write to is at the start, so we type a 0 as the second value of Write. The final value is the size of the buffer we want to create.

In case that's a little confusing, here's what's happening:

  • The NetworkStream object contacts the POP3 server for us
  • To write to the network stream, you need to set up a buffer and fill it with Bytes. The bytes you're sending are the commands you want the POP3 server to execute
  • The NetworkStream object sends your command to the server as a series of bytes
  • The POP3 Server sees the NetworkStream object, and tries to execute the command
  • It returns a response that the NetworkStream object can deal with

So that we can do something with the response that the POP3 server sends back to us, we have these two lines:

readStreamBytes = New StreamReader( networkStream )
serverResponse = readStreamBytes.ReadLine( )

The first of these two lines sets up a StreamReader. In between the round brackets of StreamReader, we type the name of our network stream. The StreamReader converts the bytes from the network stream into text. We then Read the Line or lines that were sent back, putting them into the string variable we've called serverResponse.

The final line to add to your PopCommand function is for the Catch part of your Try … Catch block is this in VB Net:

Return ex.Message

And this in C#

return ex.Message;

This returns any errors thrown up. Your function should look like this, though:

VB Net

Visual Basic .NET code to set up a stream of Bytes

C#

C# code to set up a stream of Bytes

Now that we have a function to deal with the POP3 server, we can call it into action.

To try our username on the server, add the following line to the code for your Connect button:

VB Net

txtServerResponse.Text += PopCommand( networkStream, "USER " & user) & vbCrLf

C#

txtServerResponse.Text += PopCommand(networkStream, "USER " + user) + "\r\n";

So we pass the function our network stream object. After a comma, we issue the POP3 command USER. The server is expecting the keyword USER. After a space it needs your username:

USER your_username

Underneath this, you can try your password. The line is almost identical:

VB Net

txtServerResponse.Text += PopCommand( networkStream, "PASS " & pass ) & vbCrLf

C#

txtServerResponse.Text += PopCommand(networkStream, "PASS " + pass) + "\r\n";

This time, the POP3 server needs the keyword PASS, followed by a space, then your password:

PASS your_password

The Try ... Catch block for your button code should now look like this:

VB Net

Issuing the USER command to an email server with your password

C#

C# code to issue the USER command to an email server with your password

We could do some error checking, here. Instead of returning the value from the function directly to the text box, we could test the return value for the -ERR string. For example, in VB it would:

Dim RetVal as String

RetVal = PopCommand( network_stream, "PASS" & password )

If RetVal.Substring( 0, 4 ) = "-ERR" Then

txtServerResponse.Text = "Invalid Password"
Exit Sub

End If

The code above grabs 4 characters from the start of the string that the server returned, and checks if it has a value of "-ERR".

Note that we're checking the password and not the username. That's because some servers give an +OK response, even though the username is not valid. They don't check until both username and password have been given. But in the code above, we're bailing out if the password is not accepted by the server. Though you might just want to say, "Invalid Logon" rather than giving a hint to hackers that it's just the password that's the problem.

 

Quitting the POP3 Server

We're almost ready to try it out. Before you do, create a Sub/method called QuitServer. Add the following for its code in VB Net:

Private Sub QuitServer( )

Try

Dim serverResponse As String = ""
serverResponse = PopCommand( networkStream, "QUIT" )
MessageBox.Show( serverResponse )

Catch ex As Exception

MessageBox.Show( ex.Message )

End Try

End Sub


And this, in C#:

private void QuitServer()
{

try
{

string serverResponse = "";

serverResponse = PopCommand(networkStream, "QUIT");
MessageBox.Show(serverResponse);

}
catch (Exception ex)
{

MessageBox.Show(ex.Message);

}

}

All we need to do here is to call the PopCommand function and pass it first the network stream object, then the command. In this case the server command is just QUIT.

In the code for your Quit button, call your new Sub:

VB Net

Call QuitServer( )

C#

QuitServer();

It's a good idea to call the quit Sub or method when the form is closing, rather than a button, as it's all too easy to forget to click a button. And if you forget to issue the Quit button the POP3 Server won't update.

Here's what your new code should look like (you could get rid of the Quit button altogether, if you have a Form Closing Event):

VB Net

VB NET code issuing the QUIT command to an emai server

C#

C# code issuing the QUIT command to an emai server

Try it all out. Run your programme and click your Connect button. If your Authentication details are all right, you should see something like this in your text box:

A server response message with a successful login

Click your Quit button and you should see this (though the message after +OK will differ):

A response message after issuing the QUIT command

If you get your Authentication details wrong, you may see something like this:

A server response message for a failed login

In the next lesson, you'll learn how to check if you have mail on the server

Check for email on the server >>

Back to the C# NET Contents Page

Back to the VB NET Contents Page