Educational Objectives: After completing this assignment, the student should have the following knowledge, ability, and skills:
Operational Objectives: Create a client of PWServer that simulates a password authentication system, along with a makefile that creates an executable named pwclient.x.
Deliverables: Two files pwclient.cpp and makefile.
The class PWServer is defined in the file pwserver.h. The (public) interface of a PWServer object is as follows:
PWServer (const char* infile, const char* outfile, unsigned int max);
This is the only constructor provided for the class. There are three
parameters required:
Once a PWServer object is created, these data are fixed for that object and cannot be changed during the lifetime of the object.
~PWServer ();
This is the class destructor which ensures correct destruction of each PWServer
object. The destructor is not called explicitly by the client program, rather it
is called automatically when the object goes out of scope.
int CheckPW (const char* uid, char* upw);
This method provides the most basic password service: it takes a user name
uid and a user password upw and checks the validity of the
password. The value 1 is returned if the user is authenticated and the value 0
is returned if the user is not authenticated.
Note that the second parameter which holds the password in clear text is not a "const" pointer. This allows the server to overwrite this string as soon as it is copied into a local string object, which is used as input to the secure hashing algorithm creating an associated signature. An encryption scheme could be used for this parameter to further complicate the theft of the password.
int ChangePW (const char* uid, char* upw, char* newpw);
Along with CheckPW, this is the other user accessible service: changing the
password. The three parameters required are the user name uid, the current password
upw, and the new password newpw. The service first
authenticates the user with the current password, then changes to the new
password. Both the old and new password strings are overwritten as soon as
possible by the server object. Return value 1 indicates success while return value 0
indicates failure.
int CreateUser (const char* uid, char* upw);
This and the following service are intended for use by the system management
only. They are used to create new users and remove current users from the
system. Typically, authorization to access CreateUser would be provided
by system management to a specific user. This is a potential weakness because ad
hoc identification and authentification methods are often used, for example in
the FSU CS system, the ID number is matched with the official list of CS
majors. It is not impossible for identity theft to take place at this stage of
new account generation.
Again, two parameters must be supplied, user name uid and the proposed password upw, and the value 1 is returned when the request is successful and 0 is returned when it is not successful.
int DeleteUser (const char* uid);
This is
typically accessible only by system management and has the obvious
functionality: a user name uid is purged from the authentication
system. Return value 1 indicates success while return value 0 indicates
failure.
Note that a system manager could "disable" a user by simply changing the hash value stored in the password file, so that authentication would fail. Recovering from such "disablement" could be done by copying the correct signature back over the changed value. If that correct signature is lost, however, recovery is difficult and would require another service be added to the server interface, effectively a non-password-protected ChangePW().
void Dump (std::ostream& out1 = std::cout);
This method is provided only during "white box" testing of the server. It
displays the internal contents of the server object. Note that the parameter is
a std::ostream& with a default value std::cout, so that
Dump() may be called with no explicit arguments and the results
will be sent to standard output.
The interaction of a PWServer object with its files follows a few simple rules:
The third constructor parameter is used to limit the number of users in the system that are served by a given PWServer object.
The class PWServer conforms to a standard model for controlled access to computer services known as the IAA model, where access is controlled via a three-step process:
The intended use of a password server is to provide the identification and authentication phases of the model. For more about hashing, see the lecture notes Hashing, Hash Functions, and Their Uses.
Create and work within a separate subdirectory cop3330/hw3. Review the COP 3330 rules found in Introduction/Work Rules.
Begin by copying the following files from the course directory /home/courses/cop3330p/fall08/ into your hw3 directory:
hw3/pwserver.h hw3/xstring.h hw3/pwserver_s.o hw3/pwserver_i.o hw3/pwf1.1 hw3/pwf1.2 hw3/pwf1.3 submitscripts/hw3submit.sh area51/pwclient_s.x area51/pwclient_i.x
The naming of these files uses the convention that _s are compiled for Sun/Solaris and _i are compiled for Intel/Linux. Use one of the sample client executables to experiment to get an understanding of how your program should behave.
Copy one of the distributed object files to "pwserver.o", depending on whether you are doing your development on program (Sun) or linprog (Intel). This file is the object code implementation of class PWServer defined in pwserver.h.
Create a file pwclient.cpp that contains a main program that is a client of class PWServer, i.e., that creates and uses an object of type PWServer. You should be able to make use of sample code fragments in Chapter 3 of the lecture notes in the design of this program.
Turn in two files pwclient.cpp and makefile using the hw3submit.sh submit script.
Warning: Submit scripts do not work on the program and linprog servers. Use shell.cs.fsu.edu to submit projects. If you do not receive the second confirmation with the contents of your project, there has been a malfunction.
The program must have this include statement:
#include <pwserver.h>
near the top of the file. Note that angle brackets are required. Quotes will not do.
The program must respond to the same basic menu commands as the distributed client_s.x. (This requirement is necessary for automated testing of your program.) You may add your own options as well.
The input file name for your program should be "pwf1" and the output file name for your program should be "pwf2". (This requirement is necessary for automated testing of your program.)
Compile the client with these two command:
g++ -c -I. -Wall -Wextra pwclient.cpp g++ -opwclient.x pwclient.o pwserver.o
The project should compile error- and warning-free on both program and linprog with the flags -Wall and -Wextra called in your makefile.
Test your client program. The client should behave like the supplied model area51/pwclient_s.x.
You may assume that usernames and passwords have no more than 20 characters. Use declared constants!
Create a makefile that creates pwclient.x on program and calls the compiler flags -Wall and -Wextra.
Model executables pwclient_s.x and pwclient_i.x may be copied from the area51 directory.
In addition to the necessary object files (pwserver_s.o and pwserver_i.o) in hw3, there are also pwclient_s.o and pwclient_i.o. Copying the appropriate object files for a given architecture to pwserver.o and pwclient.o, respectively, you can practice creating an executable pwclient.x with the compile command:
g++ -opwclient.x pwclient.o pwserver.o
This would allow you to develope your makefile(s) before developing the code for pwclient.cpp.
Your makefile can create a fresh copy of the required object file in the project directory. The target: dependencies and shell command would look something like:
pwserver.o: /home/courses/cop3330p/fall08/hw3/pwserver_i.o <tab> cp /home/courses/cop3330p/fall08/hw3/pwserver_i.o pwserver.o
Note that this ensures that you are using a correctly defined and named copy of pwserver.o in the working directory. (These objects files are often erased by the clean command, and this conveniently gets you a fresh copy when you need it.)
Three password files are supplied. (In all of these, the password is the same as the username.) You can create a larger file for testing purposes using the distributed area51/pwclient.x or your own. Don't forget how the file parameters are used - the output file is overwritten by the PWServer destructor, so if you add new usernames, you should copy the output file to another name before re-starting the client.