" /> UrlBlogGrey: March 2006 Archives

« February 2006 | Main | April 2006 »

March 31, 2006

VNC Clients

I've got a PC running the Fedora Core 5 distribution of Linux. Running the Secure Shell (SSH) daemon and VNC servers on the machine turns it into a wonderful terminal-server. The distribution of VNC that I use is RealVNC, developed by a team at AT&T. I could use TightVNC, which features better compression characteristics, but I've experienced weird display behavior with it in the past and prefer RealVNC's stability.

When using my PC from work, I use the RealVNC client to access any of my RealVNC servers and always experience excellent performance. I should also mention that I always tunnel my VNC connections through a secure SSH connection. Because the VNC protocol lacks encryption, it is critical that VNC traffic be tunneled through a secure channel to shield it from snoops.

When using my Macs, I use the "Chicken of the VNC" (cotvnc) application to connect to RealVNC servers. I always see greater lag over a cotvnc client connection than a RealVNC connection. I've tried matching the encoding algorithms and display characteristics on my PC and Mac, but never see the responsiveness on the Mac that I do on the PC. I'm going to continue experiementing with VNC settings, but in the meantime the difference in performance has got me scratching my head.

March 26, 2006

Installation of Fedora Core 5

I've been using Fedora Linux for about two years, and have witnessed the evolution of what I consider to be the most polished derivation of Redhat Linux yet. A major overhaul has taken place with all user-interface components, and I think that they've done a great job of "letting fresh-air in" on the Linux user-experience. The inclusion of bubbles in the new Fedora logo, and copious shades of blue make a smile come to my face. What can I say, I'm a sucker for blue.

A feature I was hoping to take advantage of was a VNC-based installation. Fedora Core 5 provides the option of having the installer start a VNC server, or connect to a remote VNC client, so that the installation can be driven over the network. Since my Linux box is normally "headless", I was excited about the possibility of conducting the installation from my Powerbook rather than dragging the PC beast over to my desk. I tried running the installation in client- and server-modes, but had luck with neither. Woe is me...

The Gnome desktop manager is a lot snappier than I remember it being in Core 4. I'm not sure if it's due to the ugprade of the X11 system, or the changes to the Core 5 themes and such. In any case, I really appreciate it!

March 23, 2006

Java PluginClassLoader

I recently researched a means for verifying the integrity and authenticity of Java archive programmatically within a Java Applet. In my case, I had an Applet that was digitally-signed and trusted by the client. The Applet downloaded and executed Java bytecode packaged in JAR files. Before loading the downloaded code, I wanted the Java Applet to verify the digital signatures of the archives using the Java Plugin's certificate-management features.

I learned that there is a ClassLoader implementation called PluginClassLoader, and is provided in Java Runtime Environments version 1.3 or better. The PluginClassLoader is an extension of the URLClassLoader and can be used only in the context of the Java Plugin. Once a JAR file has been registered with a PluginClassLoader instance, the classloader will verify that the JAR's classes loaded by it are signed by certificates trusted by the user and/or in the browser keystore.

Here is some code that, when run as an Applet, will verify the integrity of an arbitrary JAR file in its path:

String jarFileName = ...
if (file.exists() && 
	file.getName().endsWith(".jar") && 
	classLoader instanceof PluginClassLoader) 
{
	try {
		// add the JAR to the ClassLoader's context
		((PluginClassLoader)classLoader).addLocalJar(file.toURL());
		
		// attempt to load a Java class from the JAR
		JarFile jarFile = new JarFile(file, false);
		Enumeration fileEntriesEnum = jarFile.entries();
		while (fileEntriesEnum.hasMoreElements()) 
		{
			JarEntry entry = (JarEntry) fileEntriesEnum.nextElement();
			if (entry.getName().endsWith(".class"))
			{
				String className = entry.getName().replace('/', '.').replace('\\', '.').replaceFirst(".class", "");
				System.out.println("Verifying with class: " + className);
				
				// Use the PluginClassLoader to load an arbitrary class from 
                                // the archive, triggering verification
				Class.forName(className, false, classLoader);
				verified = true;
				break;
			}
		}
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

March 20, 2006

Restricting Methods of Access

My employer has an Internet gateway that limits Internet access to HTTP and HTTPS. Other services, such as e-mail (POP, IMAP) and remote shell (SSH), are not allowed to travel out based on the ports they use. This is not to say that one couldn't conduct those operations on the HTTP and HTTPS ports; however, those service ports are not designed for protocol tunneling.

This got me thinking about the futility of port restrictions. Imagine you are an evil-minded person intent on traveling to a remote destination. The authorities know your true identity, which would give you away if you used it while traveling. So, you assume a false identity while traveling and revert to your true identity once at your destination in the company of other evil-minded people. No matter what restrictions are placed on travel, evil people (or data) will be mobile so long as an alternate identity can be assumed.

The evil traveller may be discovered if the authenticity of their identity is questioned. What if, in the case of SSH and HTTPS traffic, there are no means of fingerprinting the data because it is encrypted? The interrogator could question the trustworthiness of the traveller and their source/destination. I suppose this is what happens when a person tries to travel from the U.S. to an untrusted contry (i.e. Afghanistan, Iraq). The problem on the Internet is that there is no such thing as an "untrusted site." They are all equals in the eyes of an Internet gateway. So, should there be multiple Internets to better serve corporate/government interests?

March 19, 2006

Setup for Netgear WGPS606 Print Server

I recently purchased a Netgear WGPS606 ("606") wireless print server for use on our home network. I've long been looking for a print server that would permit us to hide our huge HP Deskjet 5150 printer in the closet. It is far too expensive in terms of how much space it takes up in relation to the frequency of use.

wgps606
What made the 606 so attractive is that it is wireless (802.11g), supports WPA encryption, and can be used with Windows, Mac, and Linux systems. The only other wireless print server I've seen that supports WPA is from Linksys, but it is incompatible with Mac OS X. Since two of my computers are Macs, the Netgear won hands-down.

Installation of the print server was fairly easy, although someone less technically adept would encounter a lot of difficulty. First, my Linksys access point issues all clients IP addresses in the 192.168.1.x subnet; however, the 606 comes configured with a statically-assigned IP in the 192.168.0.x subnet. I had to manually specify the IP address on my desktop computer to place it in the 192.168.0.x subnet so that I could access the web-based configuration utility on the 606. Once I was in, I quickly configured the 606 to join my wireless network. I actually had to change my network configuration to use WPA2 with TKIP+AES, whereas I previously used strictly AES (more cryptographically robust than TKIP). Also, the 65-character key for my access point needed to be shortened to 63 characters for the 606. That was a bit annoying.

Once done configuring the 606 for network connectivity, I moved on to configuring the printer. I learned that the 606 print server can be used as a standard UNIX "Line Printer Daemon" (LPD). This is cool. The two printer ports have queues names L1 and L2, respectively. I installed the CUPS print drivers on my Macs and was printing immediately. The printing output looks great, and the queues look the same as if the printer were connected directly to my computer.

Another feature I plan to take advantage of soon is the Ethernet-bridging feature. The 606 has 4 switched-Ethernet ports on the back which can be used to connect 10-BaseT Ethernet systems to the wireless network. In my case, I have a PC running Linux that I would like to stash in the closet along with the printer. The PC would have complete network connectivity, all while being less of an eye-sore.

March 17, 2006

Java Security Manager

I recently needed to address a problem where I have a digitally-signed Java Applet running in a web browser, and the Applet creates a new native Java process to handle application operations once the Applet goes out of scope. Considering that trust is transitive, the Java application process should propagate the Applet's trust relationship established with the user.

So, I researched strategies that would ensure the Java application process checked the trustworthiness of the components used by the new Java application process. Java 2 includes a Security Manager feature which is responsible for restricting access to resources based on trust relationships established with Principals. To ensure that all Java application components used in the Java application process are trusted by the user (or their system administrator), I added a property to the Java command line invoking the default Java Security Manager:

java -Djava.security.manager -jar foo.jar

This ensures that all application resources must be trusted by the user, with that trust usually being established by way of digitally-signed JARs. Effectively, the Java application process will be run with the same restrictions placed on a Java Applet running in a web browser.

March 12, 2006

Excitement over the O'Reilly Maker Faire

I'm a big fan of the O'Reilly publication MAKE, which is a quarterly print magazine featuring DIY projects for the technology-inclined. Over the weekend of April 22-23, the Make Faire will be showcasing lots of displays from Makers around the world. The event will be held at the San Mateo fairgrounds, located in the San Francisco Bay Area.

I'm totally excited about the event! I'm looking forward mostly to displays related to robotics and wireless communications. Members of the Discovery Channel show "Myth Busters" will be at the event, which should provide some good entertainment value, too. I can't wait!

March 8, 2006

Multi-Input Networks

I am used to working with the complex communications networks employed by digital computers. In order for such networks to function, a strict set of rules must be followed by all participants in the network. A collision occurs when two or more parties attempt to transmit on a shared channel at the same time. In such a case, the parties must then attempt to re-send their information at different intervals to ensure receipt.

While driving to work last week, the signal from my iPod FM transmitter was overshadowed by a stronger signal nearby. We both had were attempting to broadcast on the FM frequency 87.9. I disconnected the transmitter from my iPod and began listening to an FM broadcast emanating from a nearby car. I could hear the broadcaster skipping songs until they settled on one they liked. It was a fun, voyeuristic-like experience.

In this case, two parties were attempting to broadcast on a shared channel and caused a collision. If the other person had a stronger signal, they may have had no idea that a collision was even occurring. Because my signal was weaker, I was plenty aware that a collision occurred - my music wasn't audible through the car stereo.

The amazing thing about analog networks is the inherent imbalance of power between participants. The one with the strongest signal wins. End of story. But, in a digital network everyone is on an even playing-field. The later is a much simpler environment to work in, and it's obvious why businesses and governments rely on digital networks for their most important operations. So what are analog networks good for?

March 5, 2006

PIC MCUs Supported in my Mac OS X Environment

There are limitations on the PIC Micro-controller Units (MCUs) I can develop with in my Mac OS X systems. This comes from 3 sources: the Microchip PICKit2 programmer, the pk2 utility that communicates with the programmer, and the HI-TIDE C-language environment I'm using to produce PIC assembly.

I've come up with an intersection of the MCUs supported by the 3 tools so that I don't make the mistake of buying an incompatible MCU in the future. Here they are:

  • 12F629
  • 12F675
  • 16F627A
  • 16F684
  • 16F877
  • 16F877A

Update: Fix to the BMW Climate Control System

My repair to the climate control system in my 1998 BMW 323 is still going strong after about 8 months. I am very thankful that I came upon the on-line information that detailed how to perform the repair. Unfortunately, it was lacking a good photo of the failed capacitor. While going through my toolbox, I came across the capacitor (kept just in case) and decided to take a photo of it before tossing. For those interested in doing the repair, here's what to look for:

Faulty Capacitor in BMW Climate Control Unit

Installation of Fink on Mac OS X Panther (10.3)

It has been a long time since I last updated the Fink installation on my Powerbook running Mac OS X Panther (10.3). I attempted to do a straight upgrade, but encountered problems related to the version of GCC (3.3) installed. So, I decided to perform a clean installation rather than muck about with settings.

Downloaded version 0.7.1 of Fink, which is the most current release compatible with Panther. Installation using the graphical installer worked fine. I then proceeded to install (download & build) the packages I've come to rely on, such as Ethereal.

March 4, 2006

Electronics Stores in the Bay Area

I purchased the Microchip PICKit 2 PIC programmer not long ago with the hopes of programming some PICs to do fancy tricks with LEDs and stuff. But I've yet to acquire a PIC that I can program with my Mac OS X computers or the PICKit 2. This has been bugging me for a while, so I decided to take a trip to the Hobby Engineering store in Milbrae this afternoon in order to buy the components I've been hankering for. Unfortunately, it isn't open on Saturdays...or Sundays...or any day that someone who actually does this stuff as a hobby would be able to make their way to Milbrae (near South San Francisco). This got me down.

I think that hobby electronics has always had the potential to draw people into a friendly setting where they can exchange project ideas and advice. The Internet has a number of message boards and mailing lists, but none of them really appeal to me. I'd love to be able to drive to a nearby electronics store and be able to exchange conversation with someone who shares a similar interest in the field. Bookstores are a good analogy: you can buy a book online if you're concerned about price and raw data, but it's hard to compete with the environments afforded by brick-and-mortar bookstores.

So, in the interest of time, I'm going to order my parts on-line. Mooo....

March 2, 2006

Java Native Interface (JNI) and Experiments in Pain

One of my recent objectives has been to integrate logging messages from a C library invoked using JNI with the logging services in the Java application. So, the path of execution is: Java to C, then C to Java. The intense intermingling of C and Java scared me at first, which was perfectly appropriate as a I would come to learn.

Providing a means of invoking C library function from Java is pretty easy. Simply define native methods in your Java class, compile the C header from the compiled Java byte-code, and develop your C functions to match those in the header. The C functions include a JNI Environment (type JNIEnv*) parameter which provides a reference to the Java runtime environment within the scope of the calling thread. The JNI Environment variable is the hub of activity in JNI world, so it's tempting to want to keep a global reference to it. But this is something you should never do, especially when it's possible that your C library will be accessed by more than one thread. I learned this the hard way...

Here's an example drawn from my work that illustrates how to make this work. When the C library is loaded by the Java application, I invoke a native method (C function) called init which sets a global variable to reference the Java Virtual Machine. This reference can be used to get a handle to the environment associated with the current thread. Very useful. Here's what the init function looks like:

// Here's the global variable for the JavaVM
JavaVM* jvm = NULL;

// global variable for the logger instance - MUST - be released in destructor to avoid 
// memory leaks
jobject logger = NULL;

JNIEXPORT void JNICALL Java_com_foo_Bar_init
  (JNIEnv *env, jobject obj)
{
	jclass loggerClass = (*env)->FindClass(env, "com/foo/LoggerFactory");
	jmethodID loggerConstr = (*env)->GetStaticMethodID(env, loggerClass, "getInstance", 
            "()Lcom/foo/ILogger;");
	logger = (*env)->CallStaticObjectMethod(env, loggerClass, loggerConstr);
	logger = (*env)->NewGlobalRef(env, logger);

	(*env)->GetJavaVM(env, &jvm);	
}

// Resonsible for deleting references to Java objects made by global variables.
void EXPORT_LIB_DESTRUCTOR destroy()
{
	JNIEnv *env = NULL;
	(*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_2);
	
	if (env && logger)
	{
		(*env)->DeleteGlobalRef(env, logger);
	}		
}

I have C function called getEnvironmentVariable, which has a handle to the JNI Environment. The JNI Environment reference is not in scope when the function lookupVar is called:

JNIEXPORT jstring JNICALL Java_com_foo_Bar_getEnvironmentVariable
  (JNIEnv *env, jobject obj, jstring var)
{
	const char *varName = (*env)->GetStringUTFChars(env, var, NULL);
	if (varName == NULL) {
		return NULL;
	}
	const char *envVal = lookupVar(varName);
	if (envVal == NULL) {
		return NULL;
	}
	jstring retval = (*env)->NewStringUTF(env, envVal);
	(*env)->ReleaseStringUTFChars(env, var, varName);
	return retval;
}

The lookupVar function may need to access logging facilities in Java. I've provided a log function which uses the jvm global variable to get a reference to the JNI Environment for the current thread:

void log (char *msg) {
	JNIEnv *env = NULL;
	(*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_2);
	if (env) {
		jstring stringMsg = (*env)->NewStringUTF(env, msg);
		loggingMethod = (*env)->GetMethodID(env, loggerClass, "debug", 
                   "(Ljava/lang/String;)V");
		(*env)->CallVoidMethod(env, logger, loggingMethod, stringMsg);
		(*env)->DeleteLocalRef(env, stringMsg);
	}				
}

This should provide a fairly complete example of how to use JNI to call back into a Java application from C without having a handle to the JNI Environment information. Here are some good resources I came across along the way: