Process-local Authentication - most local XOE information is stored in memory, i.e. not written to the filesystem. As a consequence, protection of this information can be achieved inside the XOE system, using a completely Java based password repository, which can be kept in memory, together with the information to protect. It's useless to have non-volatile passwords for volatile information, and vice-versa.
System-global Authentication - XOE has a plugin architecture, allowing
the usage of XOE-external, native programs (usually content player processes),
which can access the local filesystem. If the native, OS-specific filesystem
supports permissions, the authentication subsystem therefore should be able to
use the native, OS-based authentication system (if any).
In addition, it is possible to save/restore local content to/from a
remote server, i.e. to achieve persistency beyond a complete power-down. In this
case, user authentication data should be persistent, too (i.e. stored in the
filesystem)
Authentication Mechanism - Since XOE devices are usually point-and-click devices (i.e. don't have keyboards), it should be possible to use non-textual, hardware specific user authentication (e.g. biometrics devices).
Check Points - XOE devices are usually battery-driven, i.e. have a power saving suspend mode. User authentication therefore has to be able to take place during cold-boot and resume operations.
Device-Independent Applications - because of the portability requirement for XOE applications, the authentication subsystem has to provide a platform-/implementation- independent API, and enable the configuration of different authentication implementations.
IAuth auth = AuthFactory.getDefaultInstance(); .. if ( auth.authenticate(user,password) ){ // do protected stuff } else { System.out.println( auth.getErrorMessage( auth.getError())); }Applications use the IAuth interface to access authentication objects:
public interface IAuth { public boolean authenticate ( String user,String password ); public boolean changeAuthentication ( String user, String oldPassword, String newPassword ); public int getError(); public String getErrorMessage(); }Providing passwords as parameters to the authenticate() and changeAuthentication() calls implies the danger of storing them inside the application. While this might be Ok in case passwords are kept in memory and have restricted access (i.e. a potential native password mechanism is just used to achieve persistency), it could be counter-productive to store them in the filesystem, redundant (and less safe) than a potential native password system used by the IAuth implementation.
The example implementation is based on PAM, the "Pluggable Authentication Modules" framework, which is available for a number of Unix(-like) operating systems. This framework differentiates between
The only type which is exposed to the authentication client is the IAuth interface. The corresponding object is instantiated via a static AuthFactory class. The system allows the use of different authentication objects at the same time (for different types of requests)
The authentication subsystem makes no assumptions about the user interface. Obtaining user names and/or passwords (e.g. via user input) is outside the scope o this subsystem.
Communication with the auth process is done via a simple protocol using standard streams. Both ways are encrypted with a request specific key. This is a safeguard against (a) OS-level debugging, and (b) auth replacement.
The reasons for using an external process instead of directly linking with native authentication libraries are
While this should be theoretically sufficient, the problem here is that Java is too easy to dis-assemble, i.e. the algorithm of the reply check has to be sufficiently obscured.
Using a native library instead of an external process doesn't help, unless it is statically linked into the XOE process. Otherwise, a library would have the same authentication problems like a external program (separate file).
As simple as the authentication API is for the client, it has a flaw in that it is password-biased (exposed as call parameters). This might not be appropriate for device-based authentication. Even though the passwords don't have to be used by the pam-modules (i.e. could be null), applications passing null values implictly assume existence of such a hardware based authentication, i.e. are not portable. A common pitfall to circumvent this probably would be to store passwords somewhere else in the Java system (see above).
With respect to PAM, there should be support for pam-module controlled conversations, by means of a AuthConversation interface
public interface IAuthConversation { public String geResponse ( String message ); }
The IAuth interface would be extended by two methods
.. public boolean authenticate ( String user, IAuthConversation conv ); public boolean changeAuthentication ( String user, IAuthConversation conv );
This would solve the problem of explicit password parameters mentioned above.