CSc 423 Assignment 3

Mail Login

Assigned
Due

Feb 16
65 pts
Mar 1
Extend assignment 2 to log in to request TLS and log in to the server. Here's what mine looks like:
[bennet@bennet smtp]$ ./smlog1 smtp.gmail.com @gmailsmlog1 S: 220 smtp.gmail.com ESMTP h11-20020a81b64b000000b00607f8df2097sm60317ywk.104 - gsmtp C: EHLO 10.27.2.212 S: 250-smtp.gmail.com at your service, [167.160.210.1] S: 250-SIZE 35882577 S: 250-8BITMIME S: 250-STARTTLS S: 250-ENHANCEDSTATUSCODES S: 250-PIPELINING S: 250-CHUNKING S: 250 SMTPUTF8 C: STARTTLS S: 220 2.0.0 Ready to start TLS C: EHLO 10.27.2.212 S: 250-smtp.gmail.com at your service, [167.160.210.1] S: 250-SIZE 35882577 S: 250-8BITMIME S: 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH S: 250-ENHANCEDSTATUSCODES S: 250-PIPELINING S: 250-CHUNKING S: 250 SMTPUTF8 C: AUTH PLAIN MCSZ8aIzMHAEbyDK3kfDm92/xepJCelJp4B0zatI S: 235 2.7.0 Accepted C: HELP S: 214 2.0.0 https://www.google.com/search?btnI&q=RFC+5321 h11-20020a81b64b000000b00607f8df2097sm60317ywk.104 - gsmtp C: QUIT S: 221 2.0.0 closing connection h11-20020a81b64b000000b00607f8df2097sm60317ywk.104 - gsmtp

Additional Protocol Steps

You will need to add only a few things to your assignment 2 solution.
  1. Add a TLS layer to your socket, after connection and before adding the buffering layer. The web page downloader will show you how to do it, except send false as the third parameter, instead of the secure flag as the example does.
  2. After sending EHLO and receiving the response, send the STARTTLS command as you see above. After receving a positive response, run the start_tls() method the TLS layer object you created earlier (with false to keep TLS actually turned off). It will perform the TLS handshake with the server.
  3. Now, send EHLO again. The protocol requires this, since the list of optional features will change. In fact, if you look at the log above, you will see that STARTTLS is gone (can't start it when it's alreayd going), and various AUTH LOGIN options have appeared. (You can't log on until the connection is secure).
  4. Send the AUTH PLAIN as you see above. The string contains the the account and password encoded in base-64. More on that in a moment.
  5. Then, as before, send the help command and quit. If the server sends you an error, immediately send quit and disconnect. Log everything, as shown.

Other Changes

To accomplish login, you need to tell the program what account and password to use. You need to change the command line scanning to allow the program to be run in either of two ways:
programname hostname accountname password [ port ]
programname hostname @credfile [ port ]
In the second form, credfile is the name of a plain text file containing exactly two lines: the account name on the first, and the password on the second. This form mostly just keeps the password off the command line. Your program should open this file and read of the two lines to get the credentials. In either form, if anything is missing, or if a credential file cannot be read, just print a message and exit.

Supposedly Simple Auth

The string sent with the AUTH PLAIN command is built from three parts separated by zero bytes: An “authorization identity,” which is usually empty (and will always be for us), an account, and a password. This string is then encoded using base-64, which allows sending the zeros and other non-plain-ascii characters in the account or password. To simplify things, I'm passing along some code which will create this string for you. Send it the account and password, and it concatenates the strings and does the base-64 encoding. There are plenty of libraries that can encode base-64, but I thought it was less trouble to just code it than create an additional library dependence for the project. You can just copy this into your program, or store it in its own .cpp file and compile the file separately and link together. (For separate compilation, you will need to add #include <string> to the the authstring file, and add add the line

string authstring(string acct, string passwd);
to the main.)

An Account

You will probably not want to try this with your real email account, but create a throw-away free account for testing. The above example shows good ol' Gmail. There are other free email accounts, but for many access outside the web interface is not a free feature. To use Gmail, you will need to create an app password, so you have a bit of joyful form-filling before you. The app password is just a randomly-generated password used to log in to the mail server. Google won't let you use the same password as the one for the web site. And when I went to create one, I could not find the the “App passwords” link described in the instructions, but the search box on the page found the control for me.

I tried to use an outlook mailbox, but it does not accept auth plain. It uses XOUTH2, which i don't know much about, and have not tried to implement. The one other I was able to successfully use is GMX. For that one, after creating your account, you need to enable the remote connection. From the browser email box, choose “More” from the link index at the top, and go to E-mail settings / pop/imap, and enable pop/imap access. The SMTP server name is shown there, the account is just your full email address, and password the same one you log in to the web site with. I used standard mail submission port, 587.

Using the EHLO Response

Note that both STARTTLS and AUTH PLAIN are optional features of SMTP. The response from EHLO tells if they are supported. I've written mine to just try, and let the server respond with an error if it doesn't work. That's sort of fast-and-loose, but also easier. It allows a more sophisticated client to adapt to the capabilities of the server.

Submission

When your program is working, nicely commented and properly indented, submit it using the form here