Monday 29 September 2008

Greasemonkey improves google search result navigation

I like using the keyboard and I therefore like the possibility to navigate through google's search result with the keyboard.

Google has an experimental feature which can be activated here. But I was not able to activate this feature when a search was started from my igoogle page.

Now I found another solution: Greasemonkey together with the Google Ctrl-Arrow user script.

I learned that "Greasemonkey is a Firefox extension that allows you to write scripts that alter the web pages you visit".

Greasemonkey does nothing by itself but uses user scripts. There is a big library of user scripts.

Greasemonkey seems to be a very useful extension.

Friday 26 September 2008

My second firefox extension

Once I had a development problem and googled for a solution.
I found a page were my problem was exactly described but the solution was hidden. It was only available for registered users. Registration was not free.

So I asked my boss to get an account for this service.
In the meanwhile a colleague of mine found another solution. He checked whether the page containing the solution was in the google cache and so it was. Probably google has an account which is used by the google crawler.

Searching for a firefox extension which load the google cache for a given page I found nothing working for firefox 3, so I started an extension myself.

The extension wizard completed most of the work. It defined an entry in the context menu and the only work left was to implement the functionality behind the context menu entry. After some searching on the mozilla developer page I found the necessary snippets. This is the resulting function:

onMenuItemCommand: function(e) {
/*
* get the recently used browser window
* http://developer.mozilla.org/en/Code_snippets/Tabbed_browser
*/
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
getService(Components.interfaces.nsIWindowMediator);
var recentWindow = wm.getMostRecentWindow("navigator:browser");
if (recentWindow) {
var googleCacheUrl = "http://google.com/search?q=cache:"
+recentWindow.content.document.location;
/* open the url in a new current tab */
gBrowser.selectedTab = gBrowser.addTab(googleCacheUrl);
}
}


That's all.

The source code is available via anonymous svn with

svn co http://subversion.banapple.de/public/getgooglecache/


The extension can be installed from www.banapple.de.

Meanwhile I found an old extension which seems to do the same. It only works for Firefox 1.5.

My first firefox extension

My first firefox extensions checks the fingerprint of a ssl secured site.For online banking my bank advises me to check the fingerprint of the certificate of their site to make sure it is the right one. Every year the certificate is changed and they proclaim the new fingerprint.

So before login I always had to open the page info by clicking the lock icon, clicked show certificate and then compared the fingerprint displayed there with the one I stored in a file or on a paper. The the popups had to be closed again.

The ssl-fingerprint-check extension does all the work for me.

It can be checked out via anonymous svn with

svn co http://subversion.banapple.de/public/ssl-fingerprint-check


When I access the banks site it automatically compares the fingerprint of the certificate with a predefined value. If it matches a label in the status panel says that the fingerprint is ok or "INVALID FINGERPRINT".

The overlay file defines which xul elements are added to firefox. In this case a statusbarpanel is added to the status bar.

The rest is the javascript code to initialize the extension and handle load events which is defined in ssl-fingerprint-check.js.

Let's go through the code:

first listeners are registered such that the extension gets initialized when firefox starts and uninitialized when it stops.

window.addEventListener("load", function() { sslFingerprintCheck.init(); }, false);
window.addEventListener("unload", function() { sslFingerprintCheck.uninit(); }, false);

The init function gets the firefox browser element and adds a progress listener to it.

init: function() {
var content = document.getElementById("content");

if (content) {
content.addProgressListener(sslFingerprintCheck_urlBarListener,
Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
}
}

The current fingerprint and the common name of the certificate are hardcoded in the extension. If you want to make use of this extension you will probably have to change that or get an account in Diepholz.

var fingerprint = "ED:75:31:01:CE:09:71:3C:64:AB:EF:BD:28:AE:B5:3F:FF:87:07:B2";
var commonName = "banking.kreissparkasse-diepholz.de";

The progress listener calls the function checkCertificate on various events.
checkCertificate gets the certificate and then compares the fingerprint if the common name matches. It updates the statusbarpanel accordingly.

checkCertificate: function()
{
var certificate = sslFingerprintCheck.getCert();
if (certificate != null) {
//sslFingerprintCheck.debug("fingerprint="+certificate.sha1Fingerprint);
//sslFingerprintCheck.debug("cert="+certificate.commonName);

/* check for one specific commonName at the moment */
if (certificate.commonName == commonName) {
if (certificate.sha1Fingerprint==fingerprint) {
newLabel = "fp ok";
} else {
newLabel = "INVALID FINGERPRINT";
}
} else {
newLabel = "no banking";
}
document.getElementById("ssl-fingerprint-check-panel").label = newLabel;
} else {
document.getElementById("ssl-fingerprint-check-panel").label="no ssl";
}
}


The sites which helped to develop this extension are named in the source code.

To test the extension follow the instructions on
developer.mozilla.org section 'Test'.

Possible improvements for this extension:

  • provide a preferences window where pairs of common names and fingerprints can be managed

  • display a fancy icon for the fingerprint check instead of a label

  • display the icon in the ssl status bar panel right to the lock icon

Saturday 20 September 2008

My first thunderbird extension

I started my first thunderbird extension.
After some success at the start my motivation now rapidly decreases but I still would like to present my results.
Perhaps some information from it is helpful for other beginners.

The idea was an extension which parses a message to be displayed for text fragments matching some regular expression and then map the matching text to some link.
In my company, for example, we are using Jira.
The tickets in Jira can be accessed by URLs like
http://company-server/jira/browse/PROJECT-1
where PROJECT is an example project name in the company Jira.
I want the extension to map the text "PROJECT-1" to the ticket url.

The great vision was then to have a preferences window where regular expressions and urls can be defined, the mapped links should be displayed inline in the message text.

The source code for the extension can be downloaded via anonymous svn from http://subversion.banapple.de/public/linkator/ .

What I got in the end was an extension which was generally able to process a message and do something with it. So if you want to create an extension which manipulates a message or does some action depending on a message when it is displayed you make take my extension. There is a function called processDocument in content/overlay.js where you can implement your own stuff. The function is called when a message is displayed. You can, for example, set the background color of the message with doc.bgColor="#00FF00".

I am not really convinced if this extension makes sense at all, so my motivation was not good enough to finish it.
The parsing of the message is not finished, links are not really mapped, mapped links are not displayed in the text.
Instead only matching texts are added to a linkator box which is placed above the message.
This box is not finished because it is never cleared from old matches.
But it shows how the xul interface of thunderbird can be extended with overlays.

The extension is a mess but here is how I got there.

First I created a dummy extension with the
Extension Wizard.
To test this (already runnable) extension I inserted a file in my thunderbird profile in the extensions directory as described in http://developer.mozilla.org/en/Building_an_Extension (this page is for firefox extensions but it is all the same for thunderbird).

Then I adjusted content/thunderbirdOverlay.xul until I got a new xul element above the message.

The next step was to implement the behaviour of the extension in content/overlay.js.

I got information about how to do this from the source of other extensions
One was Remote Image Cache which showed how to hook in for message processing.

Other useful references:
The XUL tutorial at http://developer.mozilla.org/En/XUL_Tutorial
http://www.xulplanet.com/

Development was hard. To test it thunderbird always had to be restarted. I would like to hear what tools professional extension writers are using.

Monday 8 September 2008

On using the BeanShell for system introspection

At work I came across the BeanShell
and its remote server mode.

From a server application you can invoke the command

server(1234);

in a beanshell which starts a tiny HTTP server on port 1234 and a telnet session server on port 1235.
When your server at port 1234 is then accessed via HTTP you get a page containing
an applet containing a JConsole. This applet communicates with the telnet session server.

We ignored the warning about the unrestricted access to all parts of the application
and used the applet in production.

And this helped us to analyze problems we would never have been able to solve
without the remote beanshell. Before we only had logs or beans accessible via JMX.
But these information was fixed after we inserted the log statements or defined
the managed beans.
The remote beanshell allowed us to look into any object which was reachable from
one given entry point object which we set into the beanshell interpreter at startup.

We were even able to call methods on these objects to fix states we did not expect
before to happen.

One disadvantage was that the remote server was not running under the standard port 8080.
Firewall issues prevented us from accessing the remote beanshell from our workstations.
We therefore had to login to our production (windows!) web servers, start a browser there
and call the remote beanshell.

I therefore implemented a servlet providing an Interpreter instance hold in the session.
The code can be checked out via anonymous svn from
http://subversion.banapple.de/public/beanshell-extensions/

The homepage is http://www.banapple.de/beanshell-extensions/index.html.