|
Dartmouth PKI Lab Trusted Paths for Browsers |
www.cs.dartmouth.edu/~pkilab/demos/countermeasures/index.shtml Last modified: 04/24/03 02:41:28 PM |
The style of boundary, namely inset and outset, changes according to the result of a random number generator. Since the result of random number generator is unpredictable, the boundary style is unpredictable too.
So...

<window id="my-window" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<toolbar id="my-toolbar">
<hbox id="bar-buttons">
<button id="back-button" label="Back"/>
<button id="forward-button" label="Forward"/>
</hbox>
</toolbar>
</window>
/* ::::: window ::::: */
window {
padding: 0px;
background-color: #C7D0D9;
color: #000000;
font: message-box;
border-color: orange;
border-style: inset;
border-width: 15px; /*eileen*/
}
window[wait-cursor] {
cursor: wait !important;
}
window[borderStyle="true"] {
border-style: outset !important;
}
window.dialog {
padding: 7px 5px 5px 5px;
border-color: orange;
border-style: inset;
border-width: 15px; /*eileen*/
}
/* :::::externalWindow ::::: */
externalwindow {
padding: 4px;
background-color: #C7D0D9;
color: #000000;
font: message-box;
border-color: blue;
border-style: inset;
border-width: 15px; /*eileen*/
}
externalwindow[wait-cursor] {
cursor: wait !important;
}
externalwindow[borderStyle="true"] {
border-style: outset !important;
}
externalwindow.dialog {
padding: 7px 5px 5px 5px;
border-color: orange;
border-style: inset;
border-width: 15px;
}
@import url("chrome://global/global2.css");
In this global.css file, we added border to regular window which is orange color. We also defined a new window style called as externalwindow. The externalwindow has same border style and width, but with different color, blue. When window object's borderStyle attribute is set as true, the border style changes to be outset. If the borderstyle attribute is removed, the border style changes back to be inset.
/**
* the nsIBorderStyle interface which provide the random value
* true or false. JavaScript can read the random value then set .
* the window border style as inset or outset.
*
*/
/* nsISupports is the basic xpcom module */
#include "nsISupports.idl"
/**
* The uuid is a unique number identifying the interface normally
* called IID. It can be generated as follows:
*
* Windows: guidgen.exe
* Unix: uuidgen which comes with e2fsprogs package
* Mac: ???
* All platform: Using irc, connect to irc.mozilla.org and type in
* /join #mozilla
* /msg mozbot uuid
* 12/10/2001, we are in test, so we didn't register the uuid number
*
*/
[scriptable, uuid(70ab680d-a6a9-4b6e-a3c5-18504783925a)]
interface nsIBorderStyle : nsISupports
{
readonly attribute string value;
};
/* * nsBorderStyle.h is the header file of nsBorderStyleImp class * which is a particular implementation of the nsIBorderStyle interface * * this file is not machine generated. xpcom/sample/nsSample.h was used * as reference. * */ #include "nsIBorderStyle.h" #includensBorderStyleImp class inherit the public funtion of nsIBorderStyle, GetValue, also has two private functions, generateValue and setValue. GenerateValue is the random number generator function. It is called by setValue(), which check the random number and set the string which can be read by JavaScript./* * using uuidgen generated a unique identify which hopefully doesn't * conflict with other uuid. * CID for this class is * {478803ab-c024-43e4-a8ff-7a339d486185} */ #define NS_BORDERSTYLE_CID \ { 0x478803, 0xc024, 0x43e4, { 0xa8, 0xff, 0x7a, 0x33, 0x9d, 0x48, 0x61, 0x85} } #define NS_BORDERSTYLE_CONTRACTID "@mozilla.org/borderstyle;1" class nsBorderStyleImpl : public nsIBorderStyle { public: nsBorderStyleImpl(); virtual ~nsBorderStyleImpl(); /* * This macro expands into a declaration of the nsISupports interface. * Every XPCOM component needs to implement nsISupports, as it acts * as the gateway to other interfaces this component implements. You * could manually declare QueryInterface, AddRef, and Release instead * of using this macro, but why? */ NS_DECL_ISUPPORTS /* * This macro defined in nsIBorderStyle.h * NS_IMETHOD GetValue(char * *aValue); */ NS_DECL_NSIBORDERSTYLE private: /** * function generateValue is used for generating random numer 0 or 1 */ void generateValue(); /** * function to set Value according the randome generator */ void setValue(); char * mValue; int randomNumber1; // a number to remember the old random number int randomNumber2; // a number to hold the randome generator result time_t t1; // used to record current time. };
/*
* nsBorderStyle.cpp
*
* file implements nsBorderStyle.h
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "plstr.h"
#include "nsBorderStyle.h"
#include "nsMemory.h"
nsBorderStyleImpl::nsBorderStyleImpl()
{
NS_INIT_REFCNT();
mValue= PL_strdup("false"); /* initate mValue as false*/
randomNumber1 =0;
randomNumber2 =0;
t1=time(NULL);
}
nsBorderStyleImpl::~nsBorderStyleImpl()
{
if (mValue)
PL_strfree(mValue);
}
/*
* NS_IMPL_ISUPPORTS1_CI is a macro which is defined in
* nsISupportsImpl.h#740, not in #700, the lxr result is wrong!
*
* #define NS_IMPL_ISUPPORTS1_CI(_class, _interface)
* NS_IMPL_ADDREF(_class)
* NS_IMPL_RELEASE(_class)
* NS_IMPL_QUERY_INTERFACE1_CI(_class, _interface)
* NS_IMPL_CI_INTERFACE_GETTER1(_class, _interface)
*/
NS_IMPL_ISUPPORTS1_CI(nsBorderStyleImpl, nsIBorderStyle);
/**
* Notice that in the protoype for this function, the NS_IMETHOD macro was
* used to declare the return type. For the implementation, the return
* type is declared by NS_IMETHODIMP
* this function's implementation is as same as in nsSample.cpp
*/
NS_IMETHODIMP nsBorderStyleImpl::GetValue(char * *aValue)
{
/* if the timeNow is bigger than t1, that means a new random number need be generated.*/
if (time(NULL)>= t1)
setValue();
NS_PRECONDITION(aValue != nsnull, "null ptr");
if (! aValue)
return NS_ERROR_NULL_POINTER;
if (mValue) {
*aValue = (char*) nsMemory::Alloc(PL_strlen(mValue) + 1);
if (! *aValue)
return NS_ERROR_NULL_POINTER;
PL_strcpy(*aValue, mValue);
}
else {
*aValue = nsnull;
}
return NS_OK;
}
void nsBorderStyleImpl::generateValue()
{
unsigned char foo; // foo hold the unsigned char value which read out from
// "/dev/random"
int count;
int fd;
fd = open("/dev/urandom", O_RDONLY);
if (-1 == fd) {
fprintf(stderr,"error!\n");
exit(-1);
}
count = read(fd, &foo, 1);
if (count != 1) {
fprintf(stderr,"error!\n");
exit(-1);
}
randomNumber2= (int)foo%10/5;
close(fd);
printf("\n #############the new random number is: %d\n", randomNumber1);
}
void nsBorderStyleImpl::setValue()
{
/**
* setValue is called by getValue, so we are not brother by infinite loop which need
* a seperate thread.
*/
generateValue();
if( randomNumber1 != randomNumber2)
{
/* the border style has to be changed in this situation
* record the new randomNumber is randomNumber 1 for next
* cycle use.
*/
randomNumber1= randomNumber2;
if (mValue)
{
PL_strfree(mValue);
}
if ( randomNumber1 ==0)
{
mValue = PL_strdup("true");
}else
{
mValue = PL_strdup("false");
}
}
t1=time(NULL)+2;
}
GenerateValue function use Linux kernel random number generator /dev/random. According to Secure Programming for Linux and Unix HOWTO, this random number generator gathers environmental noise from device drivers and other sources into an entropy pool. When accessed as /dev/random, random bytes are only returned within the estimated number of bits of noise in the entropy pool (when the entropy pool is empty, the call blocks until additional environmental noise is gathered). When accessed as /dev/urandom, as many bytes as are requested are returned even when the entropy pool is exhausted.< script type="application/x-javascript" src="chrome://navigator/content/$Filename-changeBorder.js">in certain place. $Filename is the xul file name.
/**
* a Javascript file which change the window boundary style
**/
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var style = Components.classes["@mozilla.org/borderstyle;1"].getService(Components.interfaces.nsIBorderStyle);
function change()
{
window.setInterval("changeAttr()", 500)
}
var mainWindow;
function changeAttr()
{
mainWindow = document.getElementById("main-window");
if (style.value=="true")
{
mainWindow.setAttribute("borderStyle",true );
}else {
mainWindow.removeAttribute("borderStyle");
}
}
JavaScript need ask PrivilegeManager for the privilege to use xpconnect. Please read www.mozilla.org/scriptable/ for more information. The change function is called in window onload event. Every 500 milliseconds, changeAttr function is called to check the mValue in BorderStyleModule and do the attribute operations.You can change the interval millisecond number to affect the performance.
/* reference window is the window pop up by borderstyle module.
* so when enter_ssl warning window blocks all other threads,
* the reference window still be active to provide the right border
* style reference for the user.
*
* a gtk program compiler with
* gcc -o reference_window reference_window.c `gtk-config --cflags --libs`
*
* in order to let execl work, you have to start mozilla process
* by entering ./dist/bin/
* then start mozilla by ./mozilla
*
*/
#include <gtk/gtk.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/* viewport has two adjustments */
GtkObject *adj1, *adj2;
/*
* call back function for window close
* window close will terminate the process
*/
gint close_application( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
gtk_main_quit();
return(FALSE);
}
/*
* callback function for monitoring pipe.
* Pipe's writing end is borderStyle module.
* This is pipe's reading end
* read out from pipe and adjust the window viewport
*/
static void input_callback( gpointer data, gint fd,
GdkInputCondition condition)
{
int n;
char line[10];
char *true="true\0";
char *false="false\0";
/* read out from pipe, we used dup2 map fd[0] with STDIN_FILENO
* so here, we read from STDIN_FILENO
*/
n = read(STDIN_FILENO, line, 20);
if (strncmp( (char*)&line, true, 5) >0)
{
gtk_adjustment_set_value( (GtkAdjustment *)adj2, 245.0 );
}else{
gtk_adjustment_set_value( (GtkAdjustment *)adj2, 0.0 );
}
}
/* the main function for create the window */
void creat_window(void)
{
int i, j;
GtkWidget *window;
GtkWidget *view;
GtkWidget *table;
GtkWidget *picture_left;
GtkWidget *picture_right;
GdkPixmap *right_image_pixmap;
GdkPixmap *left_image_pixmap;
/* GdkBitmap for structures of type GdkPixmap,*/
GdkBitmap *mask_left;
GdkBitmap *mask_right;
GtkStyle *style;
/* create a new window*/
window = gtk_window_new (GTK_WINDOW_DIALOG);
/* limit window size*/
gtk_widget_set_usize(window, 145, 130);
/* after link to this singal, window close will treminate the process*/
gtk_signal_connect( GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (close_application), NULL );
/* window border width set*/
gtk_container_set_border_width( GTK_CONTAINER (window), 2 );
/* Create a 1x3 table */
table = gtk_table_new (3, 1, TRUE);
/* now for the pixmap from gdk */
style = gtk_widget_get_style( window );
/* get the GdkPixmap from the file.*/
left_image_pixmap = gdk_pixmap_colormap_create_from_xpm( window->window,
NULL, &mask_left, &style->bg[GTK_STATE_NORMAL], "./left.xpm");
right_image_pixmap = gdk_pixmap_colormap_create_from_xpm( window->window,
NULL, &mask_right, &style->bg[GTK_STATE_NORMAL], "./right.xpm");
/* get the Gtk image widget from the pixmap, */
picture_left = gtk_pixmap_new ( left_image_pixmap, mask_left);
picture_right = gtk_pixmap_new ( right_image_pixmap, mask_right);
/* Insert picture_left into the upper left quadrant of the table */
gtk_table_attach_defaults (GTK_TABLE(table), picture_left, 0, 1, 0, 1);
/* Insert picture_right into the down left quadrant of the table */
gtk_table_attach_defaults (GTK_TABLE(table), picture_right, 0, 1, 2, 3);
/* create two adjustments for viewport */
adj1 = gtk_adjustment_new (0.0, 0.0, 101.0, 1, 10.0, 10.0);
adj2 = gtk_adjustment_new (0.0, 0.0, 101.0, 1, 10.0, 10.0);
/* create the viewport */
view = gtk_viewport_new( (GtkAdjustment *)adj1, (GtkAdjustment *)adj2 );
/* let viewport contain the table */
gtk_container_add (GTK_CONTAINER (view), table);
/* let the window contain the viewport */
gtk_container_add (GTK_CONTAINER (window), view);
gtk_widget_show (window);
gtk_widget_show (view);
gtk_widget_show (table);
gtk_widget_show (picture_left);
gtk_widget_show (picture_right);
/* monitoring IO, when the pipe is ready for reading,
* input_callback is called
*/
gdk_input_add( STDIN_FILENO, GDK_INPUT_READ,
input_callback, NULL );
}
int main( int argc,
char * argv[])
{
gtk_init(&argc, &argv);
creat_window();
gtk_main();
return(0);
}
nsBorderStyleImpl::nsBorderStyleImpl()
{
NS_INIT_REFCNT();
mValue= PL_strdup("false");
randomNumber1 =0;
randomNumber2 =0;
t1=time(NULL);
/* create a pipe */
if (pipe(fd)<0)
printf("pipe error\n");
/* start a new process to run gtk program */
if ( (pid = fork())<0)
printf("fork error\n");
else if (pid >0){ /* parent process generate random number */
close(fd[0]);
write(fd[1],"false\n", 6);
}
else{ /* child process */
close(fd[1]); /*close child process' write end. */
if (fd[0] != STDIN_FILENO){
if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
printf(" dup2 error\n");
close( fd[0]);
}
/* start to run the gtk program */
if ( execl("./referenceWindow/reference_window",
"./referenceWindow/reference_window", NULL) <0)
printf(" execl error\n");
/* exit child. note the use of _exit() instead of exit() */
_exit(-1);
}
}
|
|
Back to Dartmouth PKI Lab demonstrations | Maintained by Zishuang (Eileen) Ye, eileen@cs.dartmouth.edu |