CSc 423 Assignment 2

It Goes POP

Assigned
Due

Feb 5
50 pts
Feb 19

Create a client which understands the POP3S protocol, which is POP3 as described in RFC 1939, but secured with TLS. We will use a direct, secure connection to port 995 rather than the STARTTLS command, despite RFC 1939 recommending it against it. (It's supported and simpler.) Use the Cleansocks interface to create your program. The POP3 protocol is used by mail readers to download mail from a mail server. Your program should follow the protocol, so it should work with any pop3 server.

General Operation

You are to write a program which takes the name of a POP3 server machine on the command line, connects to it on port 995 (the POP3S service). The program asks for credentials and logs into the given email account, and lists the messages in the mailbox. For this assignment, we'll just print the result of the POP LIST command, which is actually not very informative. (We'll do a better job next time.) It should also log all transactions with the server. Looks like this:

[bennet@m-mcc-csc-01456 popclient]$ pproj1 pop.gmail.com User id: tomtester723 Password: >>> +OK Gpop ready for requests from 64.246.213.1 l2mb112059490oil <<< USER tomtester723 >>> +OK send PASS <<< PASS ****** >>> +OK Welcome. <<< LIST >>> +OK 5 messages (74848 bytes) >>> 1 39986 >>> 2 15065 >>> 3 5549 >>> 4 10949 >>> 5 3299 >>> . <<< QUIT >>> +OK Farewell. [bennet@m-mcc-csc-01456 popclient]$

Test Platform

To test your program, you will need a test email account which supports POP3S. GMail does, which makes it the obvious choice, but any such service should work fine. (That's the joy of standards.) You probably don't want to use your regular email account for this; you will want to sign up for a separate account for testing. Then send it a few messages from your real account so you have something to list. The POP service is not enabled by default, so you have to sign in to your mail box, find the configure menu, and turn POP on. From the GMail web page, settings is under the (now usual) cog wheel icon, which appears near the upper right. From the drop-down, pick settings, then go to the tab “Forwarding and POP/IMAP.” Enable POP, then scroll to the bottom and save.

Once you have an account to play with, send some messages there. Then you might want to test that the pop is working using the openssl program. (You can run it from Sandbox if you don't have it installed.) Something like this:

[bennet@desktop popclient]$ openssl s_client --connect pop.gmail.com:995 --crlf -quiet depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign verify return:1 depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3 verify return:1 depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = pop.gmail.com verify return:1 +OK Gpop ready for requests from 64.246.213.1 j13mb143594323ybp USER tomtester723 +OK send PASS PASS password +OK Welcome. list +OK 5 messages (74848 bytes) 1 39986 2 15065 3 5549 4 10949 5 3299 . stat +OK 5 74848 quit +OK Farewell. read:errno=0 [bennet@desktop popclient]$
There are many more commands, but this is pretty much the dialog your client will need to make, except you don't need to use the stat command. The commands are listed in RFC 1939, and they are case-insensitive. When using the openssl s_client program, it's safer to use the lower case versions since openssl s_client treats some of the upper-case things as commands, and processes them itself instead of sending them to the server. This is not an issue with your program.

Detailed Requirements

Your program should perform the following steps, always printing both the command it sends to the server, and the response from the server.

  1. Accept a host name on the command line, as argv[1].
  2. Request an account and password on the command line. (See below about requesting passwords.)
  3. Connect to the server, receive (and print) its welcome message.
  4. Send the USER and PASS commands to log in to the server.
  5. Send the LIST command, and print the response. The response will be either an error, or an OK followed by a list of lines, one per message in the box, terminated with a line containing just a dot. Print each of these to the console. You will need to make a loop to read and print the list lines, and end after the . line.
  6. Send the QUIT command, read and print the response. Close the socket and exit.

The above assumes that all commands sent to the server are successful. If any fails, the server will return a message with a dash (-) as the first character. If that happens, after printing the line, send a QUIT, print the response, close and exit. If you get a networking error (cleansocks will throw and exception), you should close and exit. Send QUIT first if possible.

Hints

Build your client using the Cleansocks library. You will want to use cleantlsc to create a secure layer after connecting to the server. You may also want to use the buffered_socket since the POP protocol is line-oriented.

Your exchange with the server will involve a series of sending a request and reading a response. You will need to print each of these strings, as well as transmitting and receiving them. Also, you need to check the first character of each response to see if it is a + (ok) or a - (error). Break down and make a function to do this.

Passwords

As you can see from the log above, my solution does not display the password, either when entered or when the command sent to the server is echoed. You are not required to do this, but it is much nicer, and any serious application would make some effort not to print the password.

For echoing the password, I simply made a special case when echoing the password command, and printed some stars instead of the password text on the echo. (Obviously, I sent the actual password to the server.)

For reading the password without echo, you might want to use the getpass function. In Linux, you can just use it. (It is marked obsolete in the documentation, but I'll stop using it when they add a replacement.) The getpass, function will read the password in the command window without it being displayed on the screen.

Getpass is standard on Linux. There a Windows version here: header and implementation. Don't add this code to your source file, but download them and add the files to our CodeBlocks project. Then add #include "getpass.h" to your program. CleanSocks will build them correctly.

Submission

Test your program, and use appropriate indentation and comments. When you are ready, submit your program using the form here.

The output of this function is admittedly somewhat boring. We'll be doing a bit more in the next assignment.