Detecting Privilege Denial at Startup
M. Gallant 08/18/2000
This page discusses approaches for detecting the situation in which a user declines to
accept the privileges requested for running a digitally signed Java applet
within Internet Explorer or Netscape Communicator using the browsers native
JVM. Since the applet signing,
archiving and security manager mechanisms are different for the two browsers,
different approaches need to be considered. Combining this information with
browser-detection scripting
should provide sufficient information needed to code graceful recovery when a user
refuses to grant privileges.
Warning: The procedures below depend on the specific error-messages
generated by the browsers. They have only been tested on the following configurations:
Win95, WinNT4, Win2000 IE5.01, Netscape Communicator 4.73
Default browser settings are used. With IE, ensure that the Tools/Internet Options/Advanced are the default settings. |
Typical "privilege request" dialogs are:
------ Netscape Communicator (4.73 Win95) ---------
------- Internet Explorer (5.01 Win95) -----------
Internet Explorer
The JScript object model for IE Java applets enables detecting privilege-grant
status. This is only available after the page has fully loaded (and is therefore
typically called with the onLoad() event handler).
------- Approach 1 for IE (Access Java applet object String representation -------
If privileges are NOT granted,
IE reports an "ActiveX Control .." security error message (since scripted Java
applets in IE are handled by ActiveX Control technology):
whenever the applet object is accessed as a whole from JScript.
The string representation of
the document.applets[0] object for privileges NOT granted looks like:
[object]
whereas, for the usual case where privileges *are* granted, the applet object representation
contains useful information:
classname[panel52,0,0,600,300,layout=java.awt.FlowLayout]
Therefore, the following JavaScript code snippet, in an onLoad() handler function will detect
the substring "layout", and presents the user with a supplementary dialog, or could also
redirect the user to another page with further advice. [Note that only the .cab file and NOT
the .class file should be in the deployment directory]:
------- Approach 2 for IE (Access Java applet known method getCodeBase() ) -------
This approach does NOT cause the "ActiveX Control ... " message to appear.
When the user does not grant privileges, accessing the
document.applets[0].getCodeBase() method throws an IE script error:
"Object doesn't support this property or method"
and the cab file does not load.
[Note that for this method to work, ONLY the .cab file and NOT the .class file should be in the deployment directory.]
This error can handled in two different ways:
The second approach, which is only valid for IE (since try/catch is not supported in Netscape 4.7 and lower,
and cannot be caught as a JavaScript error):
In practice, the browser could be detected at initial page loading, and IE-specific
JavaScript could be loaded with:
Netscape Communicator
If privileges are denied via Netscape, the onLoad() event handler for Netscape Communicator 4.7+
does NOT get called unless the ForbiddenTargetException is caught in the Java code.
Security request calls in Netscape's object-signing technology
are embedded in the actual Java code (unlike MS Authenticode technology). Therefore, if the user
denies privileges, this can be caught within the Java code itself, using try/catch phrases. Combining
this with defining a public method and private boolean status indicator enables scripted detection
within Netscape Communicator of denied privileges. This would typically be implemented in the applet
init() method:
private boolean grantedprivileges = false;
public void init() {
try {
PrivilegeManager.enablePrivilege("UniversalPropertyRead") ;
grantedprivileges = true ;
}
catch (netscape.security.ForbiddenTargetException e) {
System.out.println("Requested privileges were not granted by user.");
return ;
}
catch(Exception cnfe) {
System.out.println("netscape.security.PrivilegeManager class not found") ;
}
// remaining init code ..
}
public boolean hasPrivileges() {
return grantedprivileges ;
}
[Note to Developers: If you include the Netscape Capabilities classes into
your win32 classpath environment (for compiling with Microsoft jvc.exe) , then IE may
find the PrivilegeManager Netscape security classes and return prematurely in the catch clause;
to cover this situation, the above code should test for the browser explicitly by using
the java.vendor System properly. Another approach is to
implement your
own security APIs for both browsers with null bodies.]
If this approach for Netscape is implemented in the Java code, the following script will
present the same JavaScript alert notification for IE or Netscape browsers when the user
denies requested privileges. The script
could also be broken up into two scripts, which would be conditionally loaded, depending on
the browser:
[Note: If privileged Java calls are made directly from JavaScript using Netscape LiveConnect technology,
the JavaScript itself must be signed. In this case, a user denying privileges generates a JavaScript
ForbiddenTargetException error (similar to and related to the Java code exception above)
that can be caught and handled using the onerror() event handler.]
Detecting root CA not installed
If the root CA certificate is not present in the Internet Explorer certificate database
(actually in the registry), the end user still gets a security dialog permitting
the end user to proceed, but warning that the code signature is not properly recognized.
If the root CA certificate is not present in Netscape's certificate
database (cert7.db file), Netscape Communicator will automatically not grant the privileges. This
situation returns the same error message as if the end user had refused privileges
in the security dialog if the root CA was present. The only way to detect the
difference between an end user explicitly denying privileges and the absence of the
root CA cert is to determine the time interval immediately before to immediately after the
privilege request is made in the Java code. If LiveConnect code is used, the timing
calculation is made in the JavaScript code just before the security call, and just inside the
error-function handler. A security dialog window takes typically > 1.5 seconds to raise, and
the end user response (to deny privileges) takes longer.
The following code snippet has been tested on Win95 and WinNT on 200 MHz Pentium systems:
function onerror(msg, URL, lineNum) {
var timetoerror = (new Date()).getTime()-presecuritytime ;
if(msg.indexOf("ForbiddenTargetException")>0) { // if Netscape security message
if(timetoerror<500)
alert("Please install the nortel PKI root CA certificate \n\n --- Time to error: " + timetoerror) ;
else
alert("You must grant the requested privileges in the dialog \n\n --- Time to error: " + timetoerror) ;
return true;
}
else
return false ; // pass up the handling chain if not Netscape error
}
// some other code here
var presecuritytime = (new Date()).getTime() ;
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserWrite');
References