diff --git a/extensions/linux/casajar/content/about.xul b/extensions/linux/casajar/content/about.xul
new file mode 100644
index 00000000..ddaa7f32
--- /dev/null
+++ b/extensions/linux/casajar/content/about.xul
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extensions/linux/casajar/content/casaOverlay.js b/extensions/linux/casajar/content/casaOverlay.js
new file mode 100644
index 00000000..eda9f407
--- /dev/null
+++ b/extensions/linux/casajar/content/casaOverlay.js
@@ -0,0 +1,370 @@
+// This is our javascript, which will pop up our message
+// in an alert box.
+
+var bGlobalPrompt = 'true';
+var consoleService = null;
+
+function logMessage(message)
+{
+ try
+ {
+ if (consoleService == null)
+ {
+ consoleService = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+ }
+
+ consoleService.logStringMessage("CASA: " + message +"\n");
+ }
+ catch (err)
+ {
+
+ }
+}
+
+
+function websso()
+{
+ logMessage("PAGE LOADED");
+ var url = window._content.location.host;
+ var enabledsite = "no";
+ var ssosite = "no";
+ var fileindex = 0;
+ var obj = null;
+
+ if (url == null || url.length < 1)
+ {
+ logMessage("Host URL not found");
+ return;
+ }
+
+ // reset loginprompt
+ bGlobalPrompt = 'true';
+
+ var para=window._content.document.getElementsByTagName("input");
+
+ for (var j = 0; !(j >= para.length) ; j++)
+ {
+ if((para.item(j).type == "password"))
+ {
+ ssosite = "yes";
+ }
+ }
+
+ if (ssosite == "yes")
+ {
+ //alert('password field found');
+ var secretId = url;
+ var sKey = "";
+ //var theValue;
+ var bAutoLogin = false;
+
+ //bGlobalPrompt = false;
+ try {
+
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ //alert('test2');
+ const cid = "@novell.com/CASA/MiCASAKeys;1";
+ if (obj == null)
+ {
+ obj = Components.classes[cid].createInstance();
+ //alert('test3');
+ obj = obj.QueryInterface(Components.interfaces.IMiCASAKeys);
+ //alert(obj);
+ }
+ }
+ catch (err)
+ {
+ logMessage(err);
+ }
+
+ var theValue = new String;
+ var res;
+
+ // does config allow sso for this site?
+
+ try
+ {
+ res = obj.miCASAReadKey(secretId, 'Config.DoNotSave', theValue);
+ if (res == 0)
+ {
+ if (theValue.value == 'true')
+ {
+ logMessage('Config does not allow SSO for this url');
+ window.removeEventListener("submit",promptuser,true) ;
+ return;
+ }
+ }
+ }
+ catch (err)
+ {
+ logMessage(err);
+ }
+
+
+
+
+ // looping for inputs and setting the correct values
+ for (var j = 0; !(j >= para.length) ; j++)
+ {
+ try
+ {
+ if((para.item(j).type == "text") || (para.item(j).type == "password"))
+ {
+ //alert(test);
+ sKey = para.item(j).name;
+ logMessage('Getting: ' + secretId + ':' + sKey);
+
+ theValue = new String;
+ res = obj.miCASAReadKey(secretId, sKey, theValue);
+
+ if (res == 0)
+ {
+ var ele = window._content.document.getElementsByName(sKey);
+ if (ele != null)
+ {
+ ele[0].value = theValue.value;
+ }
+ }
+ }
+ }
+ catch (err)
+ {
+ //alert(err);
+ }
+ }
+
+
+ try
+ {
+ res = obj.miCASAReadKey(secretId, 'autologin', theValue);
+ if (theValue.value == 'true')
+ {
+ logMessage('Autologin begins');
+ window._content.document.forms[0].submit();
+ }
+ }
+ catch (err1)
+ {
+
+
+ }
+ }
+}
+
+
+function promptuser()
+{
+ var username = "";
+ var password = "";
+ var bIsLogin = 'false';
+ var sPromptURL = "chrome://casa/content/prompt.xul?";
+ var ele=window._content.document.getElementsByTagName("input");
+ var secretID = window._content.location.host;
+
+ if (bGlobalPrompt != 'true')
+ {
+ bGlobalPrompt = 'true';
+ return;
+ }
+
+ sPromptURL = sPromptURL + "secretid=" + secretID;
+
+ for (i = 0; !(i>= ele.length); i++)
+ {
+
+ if((ele.item(i).type == "password"))
+ {
+ bIsLogin = 'true';
+ password = ele.item(i).value;
+ sPromptURL = sPromptURL + "&" + ele.item(i).name + "=" + ele.item(i).value;
+
+ // don't prompt user if password field is the same
+ try
+ {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ const cid = "@novell.com/CASA/MiCASAKeys;1";
+
+ //if (obj == null)
+ {
+ obj = Components.classes[cid].createInstance();
+ obj = obj.QueryInterface(Components.interfaces.IMiCASAKeys);
+ }
+
+ //alert("Reading");
+ var theValue = new String;
+ var res;
+ try
+ {
+ res = obj.miCASAReadKey(secretID, ele.item(i).name, theValue);
+ }
+ catch (err)
+ {
+ res = -803;
+ }
+
+ if (res == 0)
+ {
+ if (theValue.value == ele.item(i).value)
+ {
+ bIsLogin = 'false';
+ break;
+ }
+ }
+
+
+
+ } catch (err) {
+ bIsLogin = 'false';
+ }
+
+ //bIsLogin = 'true';
+ }
+ else if((ele.item(i).type == "text"))
+ {
+ username = ele.item(i).value;
+ sPromptURL = sPromptURL + "&" + ele.item(i).name + "=" + ele.item(i).value;
+ }
+ }
+
+ if (bIsLogin == 'true')
+ {
+ //if (confirm("Save credentials in CASA?"))
+ {
+ var properties = "modal=yes,status=no,titlebar=no,toolbar=no,menubar=no,location=no,height=100,width=100";
+ var win = window.open(sPromptURL, null, properties);
+ }
+ }
+ }
+
+ function centerPrompt()
+ {
+ var sh = screen.height;
+ var sw = screen.width;
+
+ sizeToContent();
+
+ var contentheight = window.innerHeight;
+ var contentwidth = window.innerWidth;
+
+ window.moveTo((sw-contentwidth)/2 , (sh-contentheight)/2);
+ }
+
+
+ function closeWin()
+ {
+ var secretID = "";
+ var sKey = "";
+ var sValue = "";
+
+ var url = document.location.toString();
+ var params = url.substring(url.indexOf('?')+1).split('&');
+
+ var remember = document.getElementById("CASA.RememberMe");
+ var autologin = document.getElementById("CASA.RemAndLogin");
+ var never = document.getElementById("CASA.Never");
+
+ try
+ {
+ //alert('test1');
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ //alert('test2');
+ const cid = "@novell.com/CASA/MiCASAKeys;1";
+ //if (obj == null)
+ {
+ obj = Components.classes[cid].createInstance();
+ //alert(obj);
+ obj = obj.QueryInterface(Components.interfaces.IMiCASAKeys);
+ //alert(obj);
+ }
+
+ } catch (err)
+ {
+ logMessage(err);
+ return;
+ }
+
+ // get the secretID (url host)
+ for (var i = 0; !(i > params.length - 1); i++)
+ {
+ sKey = params[i].substring(0, params[i].indexOf('='));
+ sValue = params[i].substring(params[i].indexOf('=')+1);
+
+ if (sKey == "secretid")
+ {
+ secretID = sValue;
+ break;
+ }
+ }
+
+
+ //alert(never.selected);
+
+ if (never.selected)
+ {
+ try
+ {
+ res = obj.miCASAWriteKey(secretID, 'Config.DoNotSave', 'true');
+ }
+ catch (err)
+ {
+ //alert(err);
+ }
+ window.close();
+ return;
+ }
+
+
+ if (remember.selected || autologin.selected)
+ {
+ // save each key-value
+ var res;
+ for (i = 0; !(i > params.length - 1); i++)
+ {
+ sKey = params[i].substring(0, params[i].indexOf('='));
+ sValue = params[i].substring(params[i].indexOf('=')+1);
+
+ if (sKey == "secretid")
+ {
+ //alert('do nothing');
+ }
+ else
+ {
+ logMessage('Writing ' + secretID + ' : ' + sKey + ' : xxxxxxx');
+ try {
+ res = obj.miCASAWriteKey(secretID, sKey, sValue);
+ if (res != 0)
+ logMessage('Error saving key');
+ }
+ catch (err)
+ {
+ logMessage(err);
+ }
+ }
+ }
+
+ if (autologin.selected)
+ {
+ //alert(" set autologin flag ");
+ res = obj.miCASAWriteKey(secretID, 'autologin', 'true');
+ }
+ else
+ {
+ res = obj.miCASAWriteKey(secretID, 'autologin', 'false');
+ }
+ }
+
+ window.close();
+ }
+
+ function cancelWin()
+ {
+ window.close();
+ }
+
+
+
+logMessage('adding event listener');
+window.addEventListener("load",websso,true) ;
+window.addEventListener("submit",promptuser,true) ;
+
diff --git a/extensions/linux/casajar/content/casaOverlay.xul b/extensions/linux/casajar/content/casaOverlay.xul
new file mode 100644
index 00000000..557be1b5
--- /dev/null
+++ b/extensions/linux/casajar/content/casaOverlay.xul
@@ -0,0 +1,13 @@
+
+
+
+
+// This imports our javascript.
+
+
+
+
+
diff --git a/extensions/linux/casajar/content/contents.rdf b/extensions/linux/casajar/content/contents.rdf
new file mode 100644
index 00000000..800c21a2
--- /dev/null
+++ b/extensions/linux/casajar/content/contents.rdf
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ chrome://casa/content/casaOverlay.xul
+
+
+
+ chrome://casa/content/casaOverlay.xul
+
+
+
+
+
+
diff --git a/extensions/linux/casajar/content/encode.js b/extensions/linux/casajar/content/encode.js
new file mode 100644
index 00000000..a4c16815
--- /dev/null
+++ b/extensions/linux/casajar/content/encode.js
@@ -0,0 +1,80 @@
+// This code was written by Tyler Akins and has been placed in the
+// public domain. It would be nice if you left this header intact.
+// Base64 code from Tyler Akins -- http://rumkin.com
+
+var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+function getBaseFilePath()
+{
+ var userAgent = navigator.userAgent.toLowerCase();
+ if (userAgent.indexOf("windows") > 0)
+ {
+ return "c:\\";
+ }
+ else
+ {
+ return "/media/CASA/CASA/";
+ }
+}
+
+
+function encode64(input) {
+ var output = "";
+ var chr1, chr2, chr3;
+ var enc1, enc2, enc3, enc4;
+ var i = 0;
+
+ do {
+ chr1 = input.charCodeAt(i++);
+ chr2 = input.charCodeAt(i++);
+ chr3 = input.charCodeAt(i++);
+
+ enc1 = chr1 >> 2;
+ enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+ enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+ enc4 = chr3 & 63;
+
+ if (isNaN(chr2)) {
+ enc3 = enc4 = 64;
+ } else if (isNaN(chr3)) {
+ enc4 = 64;
+ }
+
+ output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
+ keyStr.charAt(enc3) + keyStr.charAt(enc4);
+ } while (i < input.length);
+
+ return output;
+}
+
+function decode64(input) {
+ var output = "";
+ var chr1, chr2, chr3;
+ var enc1, enc2, enc3, enc4;
+ var i = 0;
+
+ // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
+ input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
+
+ do {
+ enc1 = keyStr.indexOf(input.charAt(i++));
+ enc2 = keyStr.indexOf(input.charAt(i++));
+ enc3 = keyStr.indexOf(input.charAt(i++));
+ enc4 = keyStr.indexOf(input.charAt(i++));
+
+ chr1 = (enc1 << 2) | (enc2 >> 4);
+ chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+ chr3 = ((enc3 & 3) << 6) | enc4;
+
+ output = output + String.fromCharCode(chr1);
+
+ if (enc3 != 64) {
+ output = output + String.fromCharCode(chr2);
+ }
+ if (enc4 != 64) {
+ output = output + String.fromCharCode(chr3);
+ }
+ } while (i < input.length);
+
+ return output;
+}
\ No newline at end of file
diff --git a/extensions/linux/casajar/content/prompt.xul b/extensions/linux/casajar/content/prompt.xul
new file mode 100644
index 00000000..035778fa
--- /dev/null
+++ b/extensions/linux/casajar/content/prompt.xul
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/linux/casajar/skin/classic/CASA_48.png b/extensions/linux/casajar/skin/classic/CASA_48.png
new file mode 100644
index 00000000..dc6efcb3
Binary files /dev/null and b/extensions/linux/casajar/skin/classic/CASA_48.png differ
diff --git a/extensions/linux/casajar/skin/classic/casa-logo.png b/extensions/linux/casajar/skin/classic/casa-logo.png
new file mode 100644
index 00000000..7b7bdbbe
Binary files /dev/null and b/extensions/linux/casajar/skin/classic/casa-logo.png differ
diff --git a/extensions/linux/casajar/skin/classic/contents.rdf b/extensions/linux/casajar/skin/classic/contents.rdf
new file mode 100644
index 00000000..ba0dd682
--- /dev/null
+++ b/extensions/linux/casajar/skin/classic/contents.rdf
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extensions/linux/mk-jar.sh b/extensions/linux/mk-jar.sh
new file mode 100755
index 00000000..849ba6f9
--- /dev/null
+++ b/extensions/linux/mk-jar.sh
@@ -0,0 +1,3 @@
+cd casajar
+zip -rD casa.jar *
+mv casa.jar ../.
diff --git a/extensions/linux/mk-xpcom.sh b/extensions/linux/mk-xpcom.sh
new file mode 100755
index 00000000..2d3c7cd9
--- /dev/null
+++ b/extensions/linux/mk-xpcom.sh
@@ -0,0 +1,3 @@
+cd src
+make
+cd ..
diff --git a/extensions/linux/mk-xpi.sh b/extensions/linux/mk-xpi.sh
new file mode 100755
index 00000000..0a4374a4
--- /dev/null
+++ b/extensions/linux/mk-xpi.sh
@@ -0,0 +1,23 @@
+if (mk-xpcom)
+then
+echo
+else
+echo '**** make xpcom failed *****'
+
+fi
+
+
+if (mk-jar)
+then
+echo
+else
+echo '**** make casa.jar failed ****'
+#exit 1
+fi
+
+cp casa.jar xpi/chrome/.
+cp src/MiCASAKeys.so xpi/components/.
+cd xpi
+zip -rD casa4linux.xpi *
+mv casa4linux.xpi ../.
+cd ..
diff --git a/extensions/linux/src/IMiCASAKeys.h b/extensions/linux/src/IMiCASAKeys.h
new file mode 100644
index 00000000..7bd44325
--- /dev/null
+++ b/extensions/linux/src/IMiCASAKeys.h
@@ -0,0 +1,101 @@
+/*
+ * DO NOT EDIT. THIS FILE IS GENERATED FROM IMiCASAKeys.idl
+ */
+
+#ifndef __gen_IMiCASAKeys_h__
+#define __gen_IMiCASAKeys_h__
+
+
+#ifndef __gen_nsISupports_h__
+#include "nsISupports.h"
+#endif
+
+/* For IDL files that don't want to include root IDL files. */
+#ifndef NS_NO_VTABLE
+#define NS_NO_VTABLE
+#endif
+
+/* starting interface: IMiCASAKeys */
+#define IMICASAKEYS_IID_STR "a3f70ce4-fae8-4bd1-98eb-0cf581e4b4dc"
+
+#define IMICASAKEYS_IID \
+ {0xa3f70ce4, 0xfae8, 0x4bd1, \
+ { 0x98, 0xeb, 0x0c, 0xf5, 0x81, 0xe4, 0xb4, 0xdc }}
+
+class NS_NO_VTABLE IMiCASAKeys : public nsISupports {
+ public:
+
+ NS_DEFINE_STATIC_IID_ACCESSOR(IMICASAKEYS_IID)
+
+ /* PRInt32 miCASAWriteKey (in AUTF8String secretId, in AUTF8String key, in AUTF8String value); */
+ NS_IMETHOD MiCASAWriteKey(const nsACString & secretId, const nsACString & key, const nsACString & value, PRInt32 *_retval) = 0;
+
+ /* PRInt32 miCASAReadKey (in AUTF8String secretId, in AUTF8String key, out AUTF8String value); */
+ NS_IMETHOD MiCASAReadKey(const nsACString & secretId, const nsACString & key, nsACString & value, PRInt32 *_retval) = 0;
+
+};
+
+/* Use this macro when declaring classes that implement this interface. */
+#define NS_DECL_IMICASAKEYS \
+ NS_IMETHOD MiCASAWriteKey(const nsACString & secretId, const nsACString & key, const nsACString & value, PRInt32 *_retval); \
+ NS_IMETHOD MiCASAReadKey(const nsACString & secretId, const nsACString & key, nsACString & value, PRInt32 *_retval);
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object. */
+#define NS_FORWARD_IMICASAKEYS(_to) \
+ NS_IMETHOD MiCASAWriteKey(const nsACString & secretId, const nsACString & key, const nsACString & value, PRInt32 *_retval) { return _to MiCASAWriteKey(secretId, key, value, _retval); } \
+ NS_IMETHOD MiCASAReadKey(const nsACString & secretId, const nsACString & key, nsACString & value, PRInt32 *_retval) { return _to MiCASAReadKey(secretId, key, value, _retval); }
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
+#define NS_FORWARD_SAFE_IMICASAKEYS(_to) \
+ NS_IMETHOD MiCASAWriteKey(const nsACString & secretId, const nsACString & key, const nsACString & value, PRInt32 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->MiCASAWriteKey(secretId, key, value, _retval); } \
+ NS_IMETHOD MiCASAReadKey(const nsACString & secretId, const nsACString & key, nsACString & value, PRInt32 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->MiCASAReadKey(secretId, key, value, _retval); }
+
+#if 0
+/* Use the code below as a template for the implementation class for this interface. */
+
+/* Header file */
+class _MYCLASS_ : public IMiCASAKeys
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_IMICASAKEYS
+
+ _MYCLASS_();
+
+private:
+ ~_MYCLASS_();
+
+protected:
+ /* additional members */
+};
+
+/* Implementation file */
+NS_IMPL_ISUPPORTS1(_MYCLASS_, IMiCASAKeys)
+
+_MYCLASS_::_MYCLASS_()
+{
+ /* member initializers and constructor code */
+}
+
+_MYCLASS_::~_MYCLASS_()
+{
+ /* destructor code */
+}
+
+/* PRInt32 miCASAWriteKey (in AUTF8String secretId, in AUTF8String key, in AUTF8String value); */
+NS_IMETHODIMP _MYCLASS_::MiCASAWriteKey(const nsACString & secretId, const nsACString & key, const nsACString & value, PRInt32 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* PRInt32 miCASAReadKey (in AUTF8String secretId, in AUTF8String key, out AUTF8String value); */
+NS_IMETHODIMP _MYCLASS_::MiCASAReadKey(const nsACString & secretId, const nsACString & key, nsACString & value, PRInt32 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* End of implementation class template. */
+#endif
+
+
+#endif /* __gen_IMiCASAKeys_h__ */
diff --git a/extensions/linux/src/Makefile b/extensions/linux/src/Makefile
new file mode 100644
index 00000000..bb839312
--- /dev/null
+++ b/extensions/linux/src/Makefile
@@ -0,0 +1,41 @@
+CXX = c++
+CPPFLAGS += -fno-rtti \
+ -fno-exceptions \
+ -shared
+
+# CASA includes
+CASA_INCLUDE_PATH = ../../../include
+
+# Change this to point at your Gecko SDK directory.
+GECKO_LIB_PATH = /usr/lib/xulrunner-1.8.0.1
+GECKO_INCLUDE_PATH = /usr/include/xulrunner-1.8.0.1
+MOZILLA_NSPR4_DEVEL = /usr/include/nspr4
+
+# GCC only define which allows us to not have to #include mozilla-config
+# in every .cpp file. If your not using GCC remove this line and add
+# #include "mozilla-config.h" to each of your .cpp files.
+GECKO_CONFIG_INCLUDE = -include mozilla-config.h
+
+#MOZILLA_STRICT_API is needed for gecko-sdk 1.7 or earlier
+#GECKO_DEFINES = -DMOZILLA_STRICT_API
+GECKO_DEFINES =
+
+CASA_INCLUDE = -I $(CASA_INCLUDE_PATH)
+XPCOM_INCLUDES = -I $(GECKO_INCLUDE_PATH) -I $(MOZILLA_NSPR4_DEVEL)
+
+GECKO_LDFLAGS = -L $(GECKO_LIB_PATH) \
+ -lxpcom \
+ -lnspr4 \
+ -lplds4
+
+FILES = MiCASAKeys.cpp MiCASAKeysModule.cpp
+
+TARGET = MiCASAKeys.so
+
+build:
+ $(CXX) -Wall -Os -o $(TARGET) $(CASA_INCLUDE) $(GECKO_CONFIG_INCLUDE) $(GECKO_DEFINES) $(XPCOM_INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $(FILES) $(GECKO_LIB_PATH)/libxpcomglue_s.a $(GECKO_LDFLAGS)
+ chmod +x $(TARGET)
+# strip $(TARGET)
+
+clean:
+ rm $(TARGET)
diff --git a/extensions/linux/src/MiCASAKeys.cpp b/extensions/linux/src/MiCASAKeys.cpp
new file mode 100644
index 00000000..7a542213
--- /dev/null
+++ b/extensions/linux/src/MiCASAKeys.cpp
@@ -0,0 +1,231 @@
+#include "MiCASAKeys.h"
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#define MODULE_NAME "MiCASAKeys.so"
+#define VERSION "1.00.0.0"
+
+void _xpcom_log (int error, const char *format, ...)
+{
+ char buffer [1024];
+ char identification [32];
+ va_list args;
+ sprintf (identification, "%s %s ", MODULE_NAME, VERSION);
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ openlog (identification, LOG_PID, LOG_AUTH);
+ setlogmask (LOG_UPTO (LOG_DEBUG));
+ syslog (error, buffer);
+ closelog ();
+ //printf("%i\t%s\t%s\n", error, identification, buffer);
+}
+
+/* Implementation file */
+NS_IMPL_ISUPPORTS1(MiCASAKeys, IMiCASAKeys)
+
+MiCASAKeys::MiCASAKeys()
+{
+ m_bLibraryLoaded = FALSE;
+ m_pCASAOpen = NULL;
+ m_pCASAClose = NULL;
+ m_pCASAWriteKey = NULL;
+ m_pCASAReadKey = NULL;
+
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAKeys constructor called.");
+
+ /* member initializers and constructor code */
+ m_hCASALibrary = dlopen("libmicasa.so", RTLD_LAZY);
+
+ if (m_hCASALibrary)
+ {
+ _xpcom_log (LOG_INFO, "libmicasa.so opened successfully.");
+
+ m_pCASAOpen = (PCASAOPEN)dlsym(m_hCASALibrary, "miCASAOpenSecretStoreCache");
+ m_pCASAClose = (PCASACLOSE)dlsym(m_hCASALibrary, "miCASACloseSecretStoreCache");
+ m_pCASAWriteKey = (PCASAWRITEKEY)dlsym(m_hCASALibrary, "miCASAWriteKey");
+ m_pCASAReadKey = (PCASAREADKEY)dlsym(m_hCASALibrary, "miCASAReadKey");
+
+ m_bLibraryLoaded = TRUE;
+ }
+ else
+ {
+ _xpcom_log(LOG_ERR, "dlopen on libmicasa.so failed, errno - %d.", errno);
+ }
+}
+
+MiCASAKeys::~MiCASAKeys()
+{
+ /* destructor code */
+// if (m_bLibraryLoaded == TRUE)
+// {
+// dlclose(hMod);
+// m_bLibraryLoaded = FALSE;
+// }
+}
+
+/* PRInt32 miCASAWriteKey (in string secretId, in string key, in string value); */
+//NS_IMETHODIMP MiCASAKeys::MiCASAWriteKey(const char *secretId, const char *key, const char *value, PRInt32 *_retval)
+
+/* PRInt32 miCASAWriteKey (in AUTF8String secretId, in AUTF8String key, in AUTF8String value); */
+NS_IMETHODIMP MiCASAKeys::MiCASAWriteKey(const nsACString & secretId, const nsACString & key, const nsACString & value, PRInt32 *_retval)
+{
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAWriteKey called.");
+
+ if (m_bLibraryLoaded == TRUE)
+ {
+ nsresult result;
+ SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
+ SSCS_SECRET_ID_T sharedId;
+ SSCS_SECRETSTORE_T ssId;
+ HANDLE context;
+
+ ssId.version = NSSCS_VERSION_NUMBER;
+ strncpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID, sizeof(ssId.ssName));
+
+ result = NSSCS_E_SYSTEM_FAILURE;
+
+ if (m_pCASAOpen)
+ {
+ context = (*m_pCASAOpen)(
+ &ssId,
+ 0,
+ NULL);
+
+ if (context)
+ {
+ sharedId.len = secretId.Length() + 1;
+ strncpy((char *)sharedId.id, secretId.BeginReading(), sizeof(sharedId.id));
+
+ if (m_pCASAReadKey)
+ {
+ result = (*m_pCASAWriteKey)(
+ context,
+ 0,
+ &sessionKeyChain,
+ &sharedId,
+ (unsigned char *)key.BeginReading(),
+ key.Length() + 1,
+ (unsigned char *)value.BeginReading(),
+ value.Length() + 1,
+ NULL,
+ NULL);
+ }
+ else
+ {
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAWriteKey - m_pCASAWriteKey is NULL.");
+ }
+
+ (*m_pCASAClose)(
+ context,
+ 0,
+ NULL);
+ }
+ else
+ {
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAWriteKey - miCASAOpenSecretStoreCache failed.");
+ }
+ }
+ else
+ {
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAWriteKey - m_pCASAOpen is NULL.");
+ }
+
+ *_retval = result;
+ return result;
+ }
+ else
+ {
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAWriteKey library not loaded.");
+ return NSSCS_E_SERVICE_NOT_FOUND;
+ }
+}
+
+/* PRInt32 miCASAReadKey (in string secretId, in string key, out string value); */
+//NS_IMETHODIMP MiCASAKeys::MiCASAReadKey(const char *secretId, const char *key, char **value, PRInt32 *_retval)
+
+/* PRInt32 miCASAReadKey (in AUTF8String secretId, in AUTF8String key, out AUTF8String value); */
+NS_IMETHODIMP MiCASAKeys::MiCASAReadKey(const nsACString & secretId, const nsACString & key, nsACString & value, PRInt32 *_retval)
+{
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAReadKey called.");
+
+ if (m_bLibraryLoaded == TRUE)
+ {
+ nsresult result;
+ SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
+ SSCS_SECRET_ID_T sharedId;
+ SSCS_SECRETSTORE_T ssId;
+ uint32_t bytesRequired;
+ HANDLE context;
+
+ ssId.version = NSSCS_VERSION_NUMBER;
+ strncpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID, sizeof(ssId.ssName));
+
+ result = NSSCS_E_SYSTEM_FAILURE;
+
+ if (m_pCASAOpen)
+ {
+ context = (*m_pCASAOpen)(
+ &ssId,
+ 0,
+ NULL);
+
+ if (context)
+ {
+ uint32_t valueLength = 256;
+ unsigned char tempValue[257];
+
+ sharedId.len = secretId.Length() + 1;
+ strncpy((char *)sharedId.id, secretId.BeginReading(), sizeof(sharedId.id));
+
+ if (m_pCASAReadKey)
+ {
+ result = (*m_pCASAReadKey)(
+ context,
+ 0,
+ &sessionKeyChain,
+ &sharedId,
+ (unsigned char *)key.BeginReading(),
+ key.Length() + 1,
+ tempValue,
+ &valueLength,
+ NULL,
+ &bytesRequired,
+ NULL);
+
+ value.Assign((char *)tempValue, valueLength - 1);
+ }
+ else
+ {
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAReadKey - m_pCASAReadKey is NULL.");
+ }
+
+ (*m_pCASAClose)(
+ context,
+ 0,
+ NULL);
+ }
+ else
+ {
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAReadKey - miCASAOpenSecretStoreCache failed.");
+ }
+ }
+ else
+ {
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAReadKey - m_pCASAOpen is NULL.");
+ }
+
+ *_retval = result;
+ return result;
+ }
+ else
+ {
+ _xpcom_log (LOG_INFO, "MiCASAKeys::MiCASAReadKey library not loaded.");
+ return NSSCS_E_SERVICE_NOT_FOUND;
+ }
+}
+
diff --git a/extensions/linux/src/MiCASAKeys.h b/extensions/linux/src/MiCASAKeys.h
new file mode 100644
index 00000000..c64722b6
--- /dev/null
+++ b/extensions/linux/src/MiCASAKeys.h
@@ -0,0 +1,90 @@
+#ifndef _MICASA_KEYS_H_
+#define _MICASA_KEYS_H_
+
+#include "IMiCASAKeys.h"
+#include
+
+#define MICASA_KEYS_CONTRACTID "@novell.com/CASA/MiCASAKeys;1"
+#define MICASA_KEYS_CLASSNAME "Common Authentication Services Adapter"
+// {287249D7-A851-4aa4-9AEE-5BCDA3B53566}
+#define MICASA_KEYS_CID { 0x287249d7, 0xa851, 0x4aa4, { 0x9a, 0xee, 0x5b, 0xcd, 0xa3, 0xb5, 0x35, 0x66 } }
+
+// External prototypes not yet in micasa.h
+typedef
+void *
+(*PCASAOPEN)(
+ SSCS_SECRETSTORE_T * ssid,
+ unsigned long ssFlags,
+ SSCS_EXT_T * ext
+ );
+
+typedef
+int
+(*PCASACLOSE)(
+ void * context,
+ unsigned long ssFlags,
+ SSCS_EXT_T * ext
+ );
+
+
+typedef
+int
+(*PCASAWRITEKEY)(
+ void * context,
+ uint32_t ssFlags,
+ SSCS_KEYCHAIN_ID_T * keyChainID,
+ SSCS_SECRET_ID_T * sharedSecretID,
+ SS_UTF8_T * key,
+ uint32_t keyLen,
+ uint8_t * val,
+ uint32_t valLen,
+ SSCS_PASSWORD_T * epPassword,
+ SSCS_EXT_T * ext
+ );
+
+typedef
+int
+(*PCASAREADKEY)(
+ void * context,
+ uint32_t ssFlags,
+ SSCS_KEYCHAIN_ID_T * keyChainID,
+ SSCS_SECRET_ID_T * sharedSecretID,
+ SS_UTF8_T * key,
+ uint32_t keyLen,
+ uint8_t * val,
+ uint32_t * valLen,
+ SSCS_PASSWORD_T * epPassword,
+ uint32_t * bytesRequired,
+ SSCS_EXT_T * ext
+ );
+
+typedef void * HANDLE;
+
+#define TRUE 1
+#define FALSE 0
+
+
+/* Header file */
+class MiCASAKeys : public IMiCASAKeys
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_IMICASAKEYS
+
+ MiCASAKeys();
+
+private:
+ ~MiCASAKeys();
+ void * m_hCASALibrary;
+ int m_bLibraryLoaded;
+
+ PCASAOPEN m_pCASAOpen;
+ PCASACLOSE m_pCASAClose;
+ PCASAWRITEKEY m_pCASAWriteKey;
+ PCASAREADKEY m_pCASAReadKey;
+
+protected:
+ /* additional members */
+};
+
+#endif //_MICASA_KEYS_H_
diff --git a/extensions/linux/src/MiCASAKeysModule.cpp b/extensions/linux/src/MiCASAKeysModule.cpp
new file mode 100644
index 00000000..9b8383b7
--- /dev/null
+++ b/extensions/linux/src/MiCASAKeysModule.cpp
@@ -0,0 +1,17 @@
+#include "nsIGenericFactory.h"
+#include "MiCASAKeys.h"
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(MiCASAKeys)
+
+static nsModuleComponentInfo components[] =
+{
+ {
+ MICASA_KEYS_CLASSNAME,
+ MICASA_KEYS_CID,
+ MICASA_KEYS_CONTRACTID,
+ MiCASAKeysConstructor,
+ }
+};
+
+NS_IMPL_NSGETMODULE("MiCASAModule", components)
+
diff --git a/extensions/linux/xpi/chrome/casa.jar b/extensions/linux/xpi/chrome/casa.jar
new file mode 100644
index 00000000..c22f8ed9
Binary files /dev/null and b/extensions/linux/xpi/chrome/casa.jar differ
diff --git a/extensions/linux/xpi/components/IMiCASAKeys.xpt b/extensions/linux/xpi/components/IMiCASAKeys.xpt
new file mode 100755
index 00000000..d27391e2
Binary files /dev/null and b/extensions/linux/xpi/components/IMiCASAKeys.xpt differ
diff --git a/extensions/linux/xpi/install.js b/extensions/linux/xpi/install.js
new file mode 100644
index 00000000..337594b2
--- /dev/null
+++ b/extensions/linux/xpi/install.js
@@ -0,0 +1,119 @@
+// install.js
+// XpiInstaller
+
+var XpiInstaller = {
+ // --- Editable items begin ---
+
+ extFullName: 'Novell CASA', // The name displayed to the user (don't include the version)
+ extShortName: 'casa', // The leafname of the JAR file (without the .jar part)
+ extVersion: '1.0',
+ extAuthor: 'CSL.Manojna',
+ extLocaleNames: null, // e.g. ['en-US', 'en-GB']
+ extSkinNames: null, // e.g. ['classic', 'modern']
+ extPostInstallMessage: 'Extension successfully installed.', // Set to null for no post-install message
+
+ // --- Editable items end ---
+
+ profileInstall: true,
+ silentInstall: false,
+
+ install: function()
+ {
+ var jarName = this.extShortName + '.jar';
+ var profileDir = Install.getFolder('Profile', 'chrome');
+
+ // Parse HTTP arguments
+ this.parseArguments();
+
+ // Check if extension is already installed in profile
+ if (File.exists(Install.getFolder(profileDir, jarName)))
+ {
+ if (!this.silentInstall)
+ {
+ Install.alert('Updating existing Profile install of ' + this.extFullName + ' to version ' + this.extVersion + '.');
+ }
+ this.profileInstall = true;
+ }
+ else if (!this.silentInstall)
+ {
+ // Ask user for install location, profile or browser dir?
+ this.profileInstall = Install.confirm('Install ' + this.extFullName + ' ' + this.extVersion + ' to your Profile directory (OK) or your Browser directory (Cancel)?');
+ }
+
+ // Init install
+ var dispName = this.extFullName + ' ' + this.extVersion;
+ var regName = '/' + this.extAuthor + '/' + this.extShortName;
+ Install.initInstall(dispName, regName, this.extVersion);
+
+ // Find directory to install into
+ var installPath;
+ if (this.profileInstall) installPath = profileDir;
+ else installPath = Install.getFolder('chrome');
+
+ // Add JAR file
+ Install.addFile(null, 'chrome/' + jarName, installPath, null);
+
+ // Register chrome
+ var jarPath = Install.getFolder(installPath, jarName);
+ var installType = this.profileInstall ? Install.PROFILE_CHROME : Install.DELAYED_CHROME;
+
+ // Register content
+ Install.registerChrome(Install.CONTENT | installType, jarPath, 'content/' + this.extShortName + '/');
+
+ // Register locales
+ for (var locale in this.extLocaleNames)
+ {
+ var regPath = 'locale/' + this.extLocaleNames[locale] + '/' + this.extShortName + '/';
+ Install.registerChrome(Install.LOCALE | installType, jarPath, regPath);
+ }
+
+ // Register skins
+ for (var skin in this.extSkinNames)
+ {
+ var regPath = 'skin/' + this.extSkinNames[skin] + '/' + this.extShortName + '/';
+ Install.registerChrome(Install.SKIN | installType, jarPath, regPath);
+ }
+
+ // Perform install
+ var err = Install.performInstall();
+ if (err == Install.SUCCESS || err == Install.REBOOT_NEEDED)
+ {
+ if (!this.silentInstall && this.extPostInstallMessage)
+ {
+ Install.alert(this.extPostInstallMessage);
+ }
+ }
+ else
+ {
+ this.handleError(err);
+ return;
+ }
+ },
+
+ parseArguments: function()
+ {
+ // Can't use string handling in install, so use if statement instead
+ var args = Install.arguments;
+ if (args == 'p=0')
+ {
+ this.profileInstall = false;
+ this.silentInstall = true;
+ }
+ else if (args == 'p=1')
+ {
+ this.profileInstall = true;
+ this.silentInstall = true;
+ }
+ },
+
+ handleError: function(err)
+ {
+ if (!this.silentInstall)
+ {
+ Install.alert('Error: Could not install ' + this.extFullName + ' ' + this.extVersion + ' (Error code: ' + err + ')');
+ }
+ Install.cancelInstall(err);
+ }
+};
+
+XpiInstaller.install();
\ No newline at end of file
diff --git a/extensions/linux/xpi/install.rdf b/extensions/linux/xpi/install.rdf
new file mode 100644
index 00000000..844b8176
--- /dev/null
+++ b/extensions/linux/xpi/install.rdf
@@ -0,0 +1,44 @@
+
+
+
+
+
+ {CE9E7AA3-C32A-444b-9BF1-703DAADC0E3C}
+ Novell CASA
+ 1.0
+ Common Authentication Service Adapter
+ CSL.Manojna
+
+ Jim Norman
+ http://www.novell.com
+ chrome://casa/skin/CASA_48.png
+ chrome://casa/content/about.xul
+
+
+
+ content/
+
+ skin/classic/
+
+
+
+
+
+ {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
+ 0.9
+ 1.5.1
+
+
+
+
+
+ {86c18b42-e466-45a9-ae7a-9b95ba6f5640}
+ 1.7
+ 1.8
+
+
+
+
+
+
\ No newline at end of file