CS2911
Lab 7

This is an old version of this course, from Fall 2016. A newer version is available here.

Resources

You can work the entire lab (except the demo) as a prelab. Although this is not required, I recommend completely writing all of your code, integrating it, and starting to work out some of the bugs before lab, so you are able to easily work out the rest of the bugs during the lab period. Please work in teams of two unless approved by the instructor. Please submit only one report per team.

Getting an early start on this lab may be as important as getting an early start on last week's lab.

To the Fall 2016 offering, from the students of the Fall 2014 and 2015 offerings of this class: The wireless in the dorms is reported to block the port needed to send email using SMTP. However, the wireless in the lobby of the dorms might work. So leave the time to go to the CC for testing, if needed. Sorry!

Installing pytz

Download the template.

In a command-prompt running as administrator, run pip install pytz tzlocal

If you get the error 'pip' is not recognized as an internal or external command, operable program or batch file., reinstall Python, being sure to check the option "Add Python 3.5 to Path"

If that does not work, please consult your instructor.

Introduction

The goal of this lab is to write a short Python program, to send an email message to an email server, using the SMTP protocol, STARTTLS security, and AUTH LOGIN authentication.

Procedure

  1. Download the skeleton Python template: smtp.py
  2. Edit the header of the file to include your team members' names, in the format provided. (Curious about the names in the template? Look them up!)
  3. Complete the smtp_send method to send an email message with at least the following content:
    • Email header
      • From
      • To (one recipient; optionally, you may add more by using a list of strings for this value)
      • Subject
      • Date
    • Email text (may be multiple lines)
    Optionally, you may add other capabilities, such as sending an attachment, but make sure that all the required functionality is completely working first.

    You will want to add other helper methods, or other named constants, but do not change any other code provided in the template.

You may not use a prebuilt library like Lib/smtplib; the point of this lab is for you to understand the low-level implementation of the SMTP protocol.

If this base functionality turns out to be too easy, you may experiment with adding additional functions, but be sure the basic requirements are still met. Make sure you always have a working backup copy before adding features.

Begin with design, and divide up the primary responsibility for parts of the program in an equitable way.

Hints and Notes

  1. You may find it helpful to interactively talk to the SMTP server, at least for the first couple commands, to get a feel for what the interaction looks like. You can do this with the Windows telnet command. On Windows 7 and beyond, you need to enable this command. Google "telnet windows 7" for instructions on how to do this.
    • To connect to SMTP: telnet smtp.office365.com 587 and type QUIT to exit -- though this will not work after STARTTLS...
    • Just for fun: telnet towel.blinkenlights.nl
  2. As in the HTTP labs, you will have to both send and receive on the TCP connection to the SMTP client. By now, you should probably have a "read line" function, and it may be helpful to have a function that can send an SMTP command and return the response (status code and accompanying data) in a form that is easy to search for a particular response line's "value".
  3. By now, you should know how to read from a network stream; if you still have questions, ask the instructor for assistance.
  4. This is a great lab for raising exceptions. See the introductory slides on Python for details. Be sure to document the exceptions you raise as in the Google style guide for methods.
  5. Getting the proper SMTP "Date" value can be a little tricky. For now, just use the provided get_formatted_date() function.
  6. To convert a non-secure TCP connection into an SSL/TLS secure connection, you can "wrap" the existing TCP socket:
    context = ssl.create_default_context()
    wrapped_socket = context.wrap_socket(old_socket, server_hostname=SMTP_SERVER)
    
    In this example, after wrapping the original old_socket, you would switch over to using the wrapped_socket for the subsequent secure operations. (Note that SMTP_SERVER is one of our named constants for this lab, defined in the template.)
  7. You can find documentation of email header elements in RFC 5322, titled Internet Message Format.
  8. When you have questions you can't resolve, consult the instructor as soon as possible, in person or by email.

Documentation style

Please follow Google's style guide for commenting methods and PEP 8 for everything else. Making sure you are documenting all arguments and return values is more important than making sure every character is right.

Excellent Credit

Like last week's lab, there is one point allocated for "excellent credit" activities beyond the requirements. One thing that would work well for this is to send an email using special UTF-8 characters, following the standards for email correctly. This could potentially require a lot of research on your part, so please don't begin this until you have the rest of the lab complete.

Submission

Please submit your file below. Please make sure your usernames are separated by hyphens and in alphabetical order.

(Acknowledgements: The original version of this lab written by Dr. Sebern.)