Permissions and Privileges
The purpose of this assignment is to add proper security features to the mailer.
- You will be given a script to take all of the mailbox names and add them as users to your system
- All mailboxes must be owned by the proper user
- You can decide on the proper permissions; however, no user should be able to read or write any other users' mailboxes or mail except that they may send them mail
- mail-out must be a privileged program in order to be able to deliver mail. You may use message-passing, setuid, or setgid, as you choose
- You may, if you wish, make mail-in privileged, but that is not required and (for some designs) not necessary
- Your system must be secure
Grading for this assignment is based on general functionality, not security under attack. Is mail delivered properly? Do all mailboxes and mail messages have the proper permissions? Have you adequately documented any special instructions, e.g., firing up a daemon?
You may use setuid, setgid, ACLs, message-passing, or any other suitable mechanisms.
Because the mailboxes—which are directories—have to be owned by the receiving user, you may have to use the sudo and chown commands to give them away. Your tree-creating script would thus be two scripts: one to create all of these mailboxes, and one, invoked via sudo, to issue the chown commands. (As a consequence, you will generally need to use sudo to delete a tree.)
To simplify testing, create a mailbox for your own userid, too. That way, you'll be able to verify that the authorized user can read their own mail but not anyone else's.
There are several possible ways to handle mailbox protection. One is to make each mailbox owned by the recipient and not readable, etc., by others. To write a message to such a mailbox, mail-out must use root privileges—but how? One way is to create the files as root and then use chown to give them away. An alternative is to use root privileges to become that user, and then create the file.
A second alternative is to use group permissions: make sure that the mailboxes are writable by some group (which you can create with the addgroup command). The mail-out command could then be setgid to that group. Think carefully about the permissions the mailboxes and the created files should have!
A third alternative is to use ACLs, to grant permissions more easily. It is possible for even a non-superuser to create an ACL granting access rights to another user. See https://linux.die.net/man/5/acl and the man pages it links to, especially https://linux.die.net/man/3/acl_set_file. (Note: ACLs are conceptually simple; the library routines are not. Also, to use ACLs on the VMs, you must first run 'sudo apt install acl'.) Again, think through file ownership and permissions.
Are there other choices? Probably!
You may, if you wish, create other programs to help implement your security solution.
The goal is security. Your design must satisfy the following properties:
- Only the intended recipient should be able to read email sent to them
- Only that person should be able to overwrite such message
- Only that person should be able to see how many are pending for them
- Although there is no ``delete'' operation in the program, your security solution must prevent anyone else from deleting email files belonging to anyone else, or in any other way causing them to lose messages that have been sent
- If mail-out (or any other helper program you create) will assume error-free input because of how it is nominally invoked, you must ensure that no one else can invoke it for their own reasons. Alternatively, these programs can do their own error-checking. For example: mail-in is supposed to format messages properly. If mail-out assumes proper formatting, your must configure things so that only mail-in can invoke it.
- It must not possible for anyone to abuse mail-in or mail-out to gain any extra privileges.
- If there are any special instructions, e.g., to fire up a daemon for a message-passing solution, you must document that in a README file. However, you are not obligated to document your design or security assumptions—those are for the attacker to find…
- Your Makefile and README file must make it simple to install your code and set up your tree with the proper ownership and permissions. You can use make variables for the location of the tree in whose bin directory things should be installed, via make TREE=dest-tree install. This target should copy all necessary executables to the proper place, including tree setup scripts. The tree setup scripts should not install your test data; that's for your attacker. However, when you submit HW4, you should include test scripts, to make life easier for the graders.
Again, grading for this assignment is based on simple functionality; the TAs will not otherwise assess your code for functionality. But watch out for hw5…
Because others will need to run your code, the requirements for deliverables are pickier and must be followed precisely.
- You must include in README a description of your security architecture: what programs are privileged and how, what permissions or ACLs you set for mailboxes, etc. If you are using ACLs, remind people to install the 'acl' package, per the instructions I've given above.
- You must explicitly list any extra users or groups that your solution requires
- You must provide two setup scripts, install-priv and install-unpriv. These scripts take exactly one argument, a destination directory that should be assumed not to exist. DO NOT TRY TO DELETE IT (but you can check if it exists, give an error message if so, and exit). Refer to this argument as $1 within the script.
- The installation scripts must create the bin, mail, and tmp directories. Permissions, ownership, and ACLs are up to you. The input directory no longer exists.
- For someone to run your code, all they should have to do is create a destination directory, unpack your file, change to that directory, and type 'make install'. That should compile your code, run install-unpriv to create all of the subdirectories, copy the executables to the bin directory, and run sudo install-priv.
- You must not modify any other system files. Your executables will be in the bin subdirectory; the tester will run them from there.
- For this assignment, submit a single tar or zip file with your source code, your scripts and Makefile, and your README file. Do not include test data. No file should contain your name, UNI, etc.
- When test runs are complete, the tester should be able to remove the created directory tree and use deluser and delgroup to delete any extra users or groups that were created by your script. These three steps should restore the system to its original condition.
The attackers in hw5 may not use root or other privileges. The attacker may, if they wish, use sudo to add extra users or groups, but may not interfere with what you create.
NOTE WELL: Because your assignments are inputs for other students' work on the next assignment, there is an extra penalty associated with late submission of this assignment. See the next assignment for details.