15-441 Project 1 -- Checkpoint 3
Checkpoint 3 is the final submission of your project. The grading rubric is
given in the project handout.
To receive the points and finish Project 1 you must:
Useful resources:
- Required CGI Environment Variables - Minimum you need to support for CGI. Biggest addition is a little parsing of the URI in requests.
- WSGI Wrapper for CGI - This is how you should wrap your Flask application that you copy-and-paste from the Flask website.
- CGI Example Code - C server-side example, Python client examples; note: it doesn't show sending of content via stdin etc.
- SSL Example Code - C server example, Python client example; note: you need to do way more SSL error handling
- Daemonizing C Code - helper daemonizing code
- Python SSL Prototype - Python web server demoing SSL socket wrapping in Python
- Python Certificates Documentation - simple de-magicifying SSL and certificates
- Begin with your repository and state of work from Checkpoint 2
- Daemonize your code using the provided code, and the passed in lock file commandline parameter. You may wish to disable daemonizing when debugging/developing.
- Create a DNS hostname for yourself with a free account at DynDNS (or already have a domain name...)
- Don't buy anything, they offer free subdomains and scripts/programs to auto-update the DNS mapping for you.
- Make sure you set this up/run the script wherever your server is running.
- If you're super confused, drop by office hours sometime and let us help you.
- Add the 15-441 Carnegie Mellon University Root CA to your browser (import certificate, usually somewhere in preferences)
- Now we can man-in-the-middle your HTTPS :-) Being course staff has perks!
- But just trust us till this part is over...or make your own CA.
- Really though, this is the part of the course where you need to Reflect on Trusting Trust.
- Obtain your own private key and public certificate from the 15-441 CMU CA.
- Implement SSL server-side.
- Use the OpenSSL library, here is a link to their documentation.
- Refer to provided Python SSL code for a high-level idea of what to do.
- Create a second server socket in addition to the first one, use the passed in SSL port from the commandline arguments.
- Add this socket to the select() loop just like your normal HTTP server socket.
- Whenever you accept connections, wrap them with the SSL wrapping functions.
- Use the special read() and write() SSL functions to read and write to these special connected clients
- In the select() loop, you need to know if a socket you are dealing with is SSL wrapped or not
- Use appropriate IO depending on the 'type' of socket---although use select() for all fd's
- Use your private key and certificate file that you obtained earlier
- If you setup your browser, you may now verify that connections to your webserver use TLSv1.0; inspect the ciphers, message authentication hash scheme, and key exchange methods used by your server.
- Implement the Common Gateway Interface (CGI RFC, URI RFC)
- CGI URI's may accept GETs, POSTs, and HEADs; your job is not to decide this, just pass along information to the program being called
- You must now parse inbound URI's to look for a special root folder, and in addition chop off arguments passed via URI according to specifications.
- Any URI starting with '/cgi/' will be handled by a single command-line specified executable via a CGI interface coded by you
- You need to pipe stdin, pipe stdout, fork(), setup environment variables per the CGI specification, and execve() the executable (it should be executable)
- Note: Watch the piped fd's in the parent process using your select() loop. Just add them to the appropriate select() sets and treat them like sockets, except you have to pipe them further to specific sockets.
- Pass any message body (especially for POSTs) via stdin to the CGI executable
- Receive any response over stdout until the process dies (monitor process status), or there is nothing more to read or broken pipe encountered
- If the CGI program fails in any way, return a 500 response to the client, otherwise
- Send all bytes from the stdout of the spawned process to the requesting client.
- The CGI application will produce headers and message body as it sees fit, you do not need to modify or inspect these bytes at all; you are a proxy...things have come full circle!
- Implement a Python Flask Blog
- Just copy and paste the entire Flask Tutorial.
- Use a virtualenv if you do not have root (you may make a relocatable one locally and upload it to servers to work with there) and can't install necessary packages.
- Submit all of the Flask blog files with your final project submission.
- DO NOT submit database files, only submit the templates and Python code.
- Instead of doing app.run() in the '__main__', you should use the WSGI wrapper function as demonstrated.
- Verify that CGI works with this blog. See what it does with your web server serving it, and what its own internal web server does.
- You can play with Flask online here.
- Submission is in the form of a 'git tag checkpoint-3 xxXXxxXXxx' which must exist in your repository by Friday 10/14 (cut off is midnight).
- Final step is to upload the tag via 'git push --tags'
Installing Flask in a non-root environment:
- wget http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.6.4.tar.gz#md5=1072b66d53c24e019a8f1304ac9d9fc5
- tar xzf virtualenv-1.6.4.tar.gz
- cd virtualenv-1.6.4
- python virtualenv.py ~/flask_env
- cd ~/flask_env/
- source bin/activate.csh
- easy_install flask
- Make your main Python script include this virtualenv in its path like in this
The ordering of these is from easiest to hardest moving from Checkpoint 2 forward. It should be relatively
straightforward to get HTTPS working. You just need to have a notion of a 'type' of socket and keep that straight
within your select() loops. CGI is a bit more difficult. You need to learn how to set environment variables according
to the CGI RFC 3875, and how to properly parse URIs according to RFC 2396 with passed in arguments. In addition, you need to handle multiple processes at once.
Thus, a lot of work will need to be devoted to CGI. You will test your CGI with your Python blog. You are encouraged to add
whatever features you'd like to your Python blog, just document them in your readme.txt.
Files we expect to see in your 'git tag checkpoint-3 xxXXxxXXxx' (fill in the x's with the commit you want to submit, don't forget to push!):