Due: Friday, September 14 by the end of the day. This means that your submission must be dated on or before that date, so you have until midnight. Note that this semester, assignments will not be accepted late.
Each assignment is graded on a 10 point scale. For this assignment, it is possible to get up to 2 extra credit points. That info is at the bottom.
Deliverables: You will be submitting your code electronically using the turnin program. Make sure that you clearly identify the members of your team (one or two people). Your program must be able to run on the UT Linux machines, so if you develop on Windows, make sure it runs on Linux.
For this assignment:
Make sure that both members of your team understand the code and contribute equally, as much as possible, to its development. If anyone gets a free ride, they'll be disadvantaged later.
Your assignment is to implement in Java a simple "secure" system following the Bell and LaPadula (BLP) security rules--simple security, the *-property, and strong tranquility. Take care with this assignment, because it will form the basis of one subsequent assignment.
Imagine that the input for your system is a file of commands. For the current assignment, legal commands are of the form:
READ subject_name object_name WRITE subject_name object_name value
All fields of the instruction are Strings except the value, which is an integer.
You will read successive lines from the file and parse each into an InstructionObject class object. Commands are not case-sensitive, even object and subject names. Arbitrary whitespace is allowed in commands, though you can assume that each command is on one line.
Be sure to deal with the possibility of errors in the instructions (neither READ nor WRITE, wrong number of arguments, etc.). For illegal instructions, generate a BadInstruction constant object.
For example, suppose your input file contains the following instructions. The top two and the last three are bad and the others syntactically legal.
write Hal HObj read Hal write Lyle LObj 10 read Hal LObj write Lyle HObj 20 write Hal LObj 200 read Hal HObj read Lyle LObj read Lyle HObj foo Lyle LObj Hi Lyle,This is Hal The missile launch code is 1234567Notice that you're not checking security attributes or definedness of the subjects/objects (yet), merely the syntactic well-formedness of the commands.
Assuming that Hal and Lyle are subjects and LObj and HObj are objects, we might write an interpreter for this system, that would perform the legal instructions and ignore the others. A reasonable implementation might end with a state in which the objects have values: LObj 200 and HObj 20; the subjects' TEMP variables would contain: Hal 20 and Lyle 20.
In the secure version of our system, whenever a subject requests to perform an action (READ or WRITE), the action is submitted to the reference monitor, which decides whether to perform the action or not based on the BLP properties (Simple Security and the *-Property). If legal and allowed by the BLP rules, the reference monitor tells the ObjectManager to perform the appropriate action; otherwise, no objects are accessed. Commands referencing any subject/object that does not exist on the system are treated as not permitted. The reference monitor always returns an integer value to the subject: the value of the object read, if the command was a legal READ; and 0 otherwise. If the subject is performing a READ, it stores this value into its TEMP variable. Think of the reference monitor as a firewill around the ObjectManager. Note that the ObjectManager doesn't know or care about labels or security; it just performs simple accesses.
Think of the top level class (SecureSystem) as managing subjects and the reference monitor but also serving as the interpreter. It reads successive instructions from the instruction list, parses them, and submits them to the reference monitor, which performs them (or not). The value returned by the reference monitor is passed to the subject executing the instruction.
Your task is to implement all this, subject to the following constraints.
The main function in your SecureSystem class should perform the following tasks:
Below is a snippet of code from my main function. You don't have to follow this model, but you're welcome to.
// LOW and HIGH are constants defined in the SecurityLevel
// class, such that HIGH dominates LOW.
SecurityLevel low = SecurityLevel.LOW;
SecurityLevel high = SecurityLevel.HIGH;
// We add two subjects, one high and one low.
sys.createSubject("Lyle", low);
sys.createSubject("Hal", high);
// We add two objects, one high and one low.
sys.getReferenceMonitor().createNewObject("Lobj", low);
sys.getReferenceMonitor().createNewObject("Hobj", high);
...
While designing your system consider the following questions: Are there security flaws in this design? What are they? How might you go about fixing them?
As an example of the execution, given the instruction list from
Part 1, my implementation gives the following output. (Note that none
of this output would ordinarily be visible to Hal and Lyle.)
> java SecureSystem instructionList Reading from file: instructionList Bad Instruction The current state is: LObj has value: 0 HObj has value: 0 Lyle has recently read: 0 Hal has recently read: 0 Bad Instruction The current state is: LObj has value: 0 HObj has value: 0 Lyle has recently read: 0 Hal has recently read: 0 lyle writes value 10 to lobj The current state is: LObj has value: 10 HObj has value: 0 Lyle has recently read: 0 Hal has recently read: 0 hal reads lobj The current state is: LObj has value: 10 HObj has value: 0 Lyle has recently read: 0 Hal has recently read: 10 lyle writes value 20 to hobj The current state is: LObj has value: 10 HObj has value: 20 Lyle has recently read: 0 Hal has recently read: 10 hal writes value 200 to lobj The current state is: LObj has value: 10 HObj has value: 20 Lyle has recently read: 0 Hal has recently read: 10 hal reads hobj The current state is: LObj has value: 10 HObj has value: 20 Lyle has recently read: 0 Hal has recently read: 20 lyle reads lobj The current state is: LObj has value: 10 HObj has value: 20 Lyle has recently read: 10 Hal has recently read: 20 lyle reads hobj The current state is: LObj has value: 10 HObj has value: 20 Lyle has recently read: 0 Hal has recently read: 20 Bad Instruction The current state is: LObj has value: 10 HObj has value: 20 Lyle has recently read: 0 Hal has recently read: 20 Bad Instruction The current state is: LObj has value: 10 HObj has value: 20 Lyle has recently read: 0 Hal has recently read: 20 Bad Instruction The current state is: LObj has value: 10 HObj has value: 20 Lyle has recently read: 0 Hal has recently read: 20
The assignment above is unrealistic in that the actions of subjects Lyle and Hal are synchronized according to the ordering of instructions in the input. Reimplement this assignment so that Lyle and Hal run as separate processes (threads), each reads from its own instruction file (remove the subject name argument to each instruction), and they share the reference monitor.
If you do this in the most straightforward way, they will run in an arbitrarily interleaved fashion depending on the OS scheduling. If the instruction lists are short, whichever one gets the processor first likely will just blow through his instruction list, finishing before the other thread ever runs. Add an additional SLEEP instruction that relinguishes the processor. I.e., if Hal is running and executes a SLEEP instruction, then the processor should be handed to Lyle, etc. That way you can force interesting interleavings. Note that this may not work as expected on multi-processor systems where the threads are scheduled on separate processors. Also, printing of the output may be oddly interleaved. Don't worry about that.
If you're having problems with the threads programming, these may help. Here is an excellent description of Java Synchronization by Ron Rockhold: Java Synchronization, and a link to helpful short paper by Prof. Mike Dahlin: Threads Programming.