Sunday, August 31, 2008

Implementing your own encoder in the Encoder Tool

As I already mentioned in the Encoder's introduction post, the main feature of the Encoder Tool is an extensibility. Meaning that you can implement your own encoders and plug them to the Encoder Tool.

In this guide, I'll explain how to create a custom encoder and plug it into the Encoder Tool. This guide applies to the current Encoder's version (0.2.0).

Create Java Project


Download the distribution of the Encoder (zip file) and create a java project. Add an encoder's jar and third-parties jars from the lib folder to the project's classpath.

Create an Encoder's Class


Create a new class that extends tarlog.encoder.tool.api.AbstractEncoder.

Implement encode() Method


This is the most important method to implement, the method that is responsible to the encoder's logic. First, you'll need to pay attention that there are two encode methods that you can override:
* Object encode(String source)
and
* Object encode(byte[] source)
You must override at least one of these methods, but usually you will override only one.

So what is the difference?
Object encode(String source) is invoked when the input is a text.
Object encode(byte[] source) is invoked when the input is a byte array.
Simple, isn't it?

The default implementation of these methods is to call each other, which leads to endless recursion if you don't implement one of the methods. The Encoder Tool asserts that you implement one of the methods and will throw an exception if you don't.

The result of the encode method should be either a String or a byte array. If other object is returned, its toString() method will be invoked. If null is returned, the output will remain unchanged.

Example


package tarlog.encoder.tool.encoders;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import tarlog.encoder.tool.api.AbstractEncoder;

public class MyUrlEncoder extends AbstractEncoder {

@Override
public Object encode(String source) {
try {
return URLEncoder.encode(source, "UTF-8");
} catch (UnsupportedEncodingException e) {
showException(e);
return null;
}
}
}


Plug in a Customer Encoder to the Encoder Tool


To plugin in a custom encoder to the Encoder Tool do the following:
1. Open preferences page and add a new encoder. You can add it either to the existing group or you can create a new group.
2. When you add the encoder, you should provide a name, a class name and a classpath.
3. Define classpath of the encoder, it may contain class folders or jars.
4. Press OK and start using your encoder.

Conclusion


In this post I have described how to create custom encoders to the Encoder Tool. As you could see, it's very very simple. However, you may say, what happens if the custom encoder needs an additional input? Just like the "Digital Signatures" encoders. So there is solution for this, but it will have to wait for the next post.

Friday, August 29, 2008

Encoder 0.1.0

And here just another neat tool I have developed for my personal needs and decided to make it public. Meet the Encoder!

So what is it used for?


It is used to encode things from one format to another. The input can be either text or bytes and the same about output. The tool is easily extendable: if you need to perform some special encoding you can implement encoder yourself and plug it into the tool. I'll expand about this functionality in the later post.

Built-in Encoders


Currently the build-in encoders are:
  • To/From Base64
  • Url Encoder/Decoder
  • Inflate/Deflate (optionally uses gzip)
  • Create signature using a private key
  • Verify signature using a public key
  • Verify signature using a certificate


Running the tool


The tool can be run either as an eclipse plugin or as a standalone application. UI is implemented in SWT, which makes it cross-platform. To run the Encoder standalone, download the distribution zip and execute "javaw -jar encoder-0.1.0.jar". You'll need at least Java 5.

I guess that all for now. I'll be happy to get any feedback about the Encoder and see people using it.

Enjoy!

Tuesday, August 26, 2008

tarlog-plugins 1.2.2

Only 48 hours since 1.2.1 was released, I'm releasing another fix to the tarlog-plugins.

It fixes the redundant cmd process that is left in memory after the cmd is closed. See Issue 3 for more details.

Monday, August 25, 2008

tarlog-plugins 1.2.1

18 downloads in about a month and one opened defect. I think it's pretty nice for the plugin I wrote for my personal needs and advertised only in this blog.

So now I'm releasing version 1.2.1 of the tarlog-plugins.
It contains the fix to the only defect I got from the outside world and a fix to the defect I opened myself.

Just to remind you the features of the plugin:

  • Open in Command Prompt - opens command prompt from the current file or folder in the Eclipse's Package Explorer/Navigator.

  • Open in Windows Explorer - opens windows explorer with the selection on the current file or folder in the Eclipse's Package Explorer/Navigator.

  • Templates for apache-commons-logging.


I'm working with Eclipse 3.4 and I use this plugin only there. So I'm not quite sure if it will work with the previous versions of Eclipse.

Saturday, August 23, 2008

Desktops v1.0

Mark Russinovich and Bryce Cogswell have recently released a Desktops application as part of the Sysinernal Suite. Desktops allows you to organize your applications on up to four virtual desktops. Read email on one, browse the web on the second, and do work in your productivity software on the third, without the clutter of the windows you’re not using. Unix users are usually familiar with this feature and have it built in their UI frameworks. But in Windows it was always missing.
Especially nice that it comes in one file of 117KB size and requires no installation.

Thanks to LiM for first sharing this stuff.

Thursday, August 14, 2008

Verifying Signatures of the Query Parameters

Recently I have spent few hours trying to understand why the verification of the digital signature of the parameter, which was sent as query parameter on the url, fails.

I put two logging messages on the parameter: one at request as it arrives, before any parsing is done at all and one just before the signature verification.

When verifying the first output, the verification was successful, but the second one was failing. "What a voodoo!" - thought I, and decided to compare this string in text edit. You know to take one string, type "Search" and try to find the second one. It succeeded. "Voodoo!" - thought I again. How the strings can be identical in a text editors and have a different signature?

If you want to think about it, just stop reading here and think.

Personally I started thinking about some hidden characters and so on... But the answer was much simple: Text editor compare text ignoring the case. It's so obvious that we usually don't think about it. Some (very few) of the characters of the text had a different case and that's why the text editor found them, but the signature failed.

However, another question was left: How happened that the query parameter, which was sent on the url, changed the case of some of its characters? The answer is a bit tricky. The parameter that is sent on the url should be url-encoded. The sender was encoding the url before creating a digital signature. The receiver was aware of this functionality and moreover he was also aware that the servlet container decodes the parameters as it receives them. So the receiver was encoding the parameter back to url-encoded format before validating the signature and everything worked.
Until one day came another sender, who did exactly the same logic, but who used a different library for the url encoding. He used lower case characters for the encoded values instead of the upper case characters that are usually used by most of the libraries.

So the scenario for the incorrect behavior is clear. And where is the defect?
The defect is in the receiver's part of code. Receiver should never get parameters from the servlet container, but get the whole query string before it's going to be parsed and do the parsing by himself. It's incorrect to do the parsing and then to correct the parsing errors by url-encoding the parameter back to its original state. The parameter should be verified as is.