Log <-

Archive for the ‘tech’ Category

RSS   RSS feed for this category

Simple Revision Control with RCS

Tuesday, June 9th, 2009

I do a lot of stuff in text file on my system. I keep notes and todo's in them, I write drafts using a text editor and even complete user guides and other documentation. I also keep my personal planning in Gnome Planner which stores its data in an XML file, which in essence is also text. Every so often I wish I could revert a draft back to an older version, or perhaps just have little peak at how it was a couple of days ago. I also really wanted to be able to look back at my planning to see where I made mistakes and underestimated the time required for a particular task.

A revision control system would be ideal in these circumstances. However a full-featured revision control system such as Subversion or Git would be a little overkill in this situation. Enter our old and forgotten friend RCS. RCS has been around since at least 1982, and has since been deprecated by CVS, Subversion and the various other centralized and decentralized versioning systems. It is however perfectly suited for keeping revision histories of single or a small collection of files. RCS is easier to understand than just about any other revision control system too.

Let's look at how it works. First, we have to install it. It used to be installed by default on most systems, but that's no longer the case. If you're running a Debian-based distribution (such as Ubuntu), you can simply install it by typing:

aptitude install rcs

We've now got the RCS revision system installed, and we can start using it.

Let's create an empty text file, called 'simplerevisioncontrolwithrcs.txt' in the 'drafts' directory:

~$ cd drafts
~/drafts$ touch simple_revision_control_with_rcs.txt

RCS consists of a couple of simple command-line utilities:

  • 'ci': Check In RCS revisions. This allows you to save the changes made to a file that is managed by RCS.
  • 'co': Check out RCS working copy. This command retrieves a specific version (the latest by default) of a file in a RCS repository.

So let's convert our empty draft to an RCS repository by checking it in. This means RCS will create a file based on the file you want to check in with the appropriate information such as when it has been been changed, what changed, etc.

~/drafts/$ ci simple_revision_control_with_rcs.txt
simple_revision_control_with_rcs.txt,v  <--  simple_revision_control_with_rcs.txt
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
>> Simple revision control with RCS
>> .
initial revision: 1.1
done

There. Our initial empty file is gone, and in its place is a file under RCS revision control: 'simplerevisioncontrolwithrcs.txt,v'. It has been given a revision number by RCS: revision 1.1.

We can now make a working copy of this file by doing a checkout. This will retrieve the latest modifications from the text file and create a new file with the original name in the current directory. The first thing we should do though, is to turn off locking. We're working on this file ourselves, and it will never be shared, so we don't care about locking at all. Locking can be turned off using the '-U' option of the 'rcs' tool:

~/drafts$ rcs -U ./simple_revision_control_with_rcs.txt,v 
RCS file: ./simple_revision_control_with_rcs.txt,v
done

Now we can do a checkout so we can edit our draft. Let's do this, and add a line to it:

~/drafts$ co simple_revision_control_with_rcs.txt,v 
simple_revision_control_with_rcs.txt,v  -->  simple_revision_control_with_rcs.txt
revision 1.1
done
~/drafts$ echo "Hello world" > simple_revision_control_with_rcs.txt

Now let's commit this change to the repository so RCS knows about it:

~/drafts$ ci simple_revision_control_with_rcs.txt
simple_revision_control_with_rcs.txt,v  <--  simple_revision_control_with_rcs.txt
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single '.' or end of file:
>> Added greeting.
>> .
done

RCS keeps an entire history of all changes made to the files it keeps under revision each time you do a check in. Take a look at the history of the file with the command 'rlog':

~/drafts$ rlog ./simple_revision_control_with_rcs.txt,v
RCS file: ./simple_revision_control_with_rcs.txt,v
Working file: simple_revision_control_with_rcs.txt
head: 1.2
branch:
locks: non-strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 2; selected revisions: 2
description:
Simple revision control with RCS
----------------------------
revision 1.2
date: 2009/06/09 07:48:50;  author: todsah;  state: Exp;  lines: +1 -0
Added greeting.
----------------------------
revision 1.1
date: 2009/06/09 07:46:24;  author: todsah;  state: Exp;
Initial revision
=============================================================================

That lists some basic information on the file, the repository and the two revisions we've made so far. We can now easily check out earlier revisions of the file by specifying a specific revision, or a date:

~/drafts$ co -r1.1 simple_revision_control_with_rcs.txt
simple_revision_control_with_rcs.txt,v  -->  simple_revision_control_with_rcs.txt
revision 1.1
done
~/drafts$ cat simple_revision_control_with_rcs.txt
~/drafts$

RCS has given us back our file as it existed at revision 1.1, which was the empty file. Let's retrieve the version of the file as it was at 14:00 today:

~/drafts$ co -d"14:00" simple_revision_control_with_rcs.txt,v
simple_revision_control_with_rcs.txt,v  -->  simple_revision_control_with_rcs.txt
revision 1.2
writable simple_revision_control_with_rcs.txt exists; remove it? [ny](n): y
done

In conclusion: RCS may appear to be completely dead, but it still has its uses. I know many people out there will think to themselves "Why not just use Git or Subversion"? I understand the attraction of very powerful tools, but I also really believe in keeping things simple, and using the right tool for the job. I don't know much about Git, so perhaps it is ideal for such a simple requirement, but I don't really feel like learning it just to version control a single file.

Performance optimization: The first thing to do

Sunday, April 19th, 2009

In the last couple of years, I've done a lot of performance optimization. I've optimized raw C, Python and PHP code. I've optimized databases: tweaked settings, memory usage, caches, SQL code, the query analyzer, hardware and indexes. I've optimized templates for disk I/O, compilation and rendering. I've optimize various caches and all kinds of other stuff like VMWare configurations.

As I've done a lot of optimization, I've noticed a couple of things. One of these things is how persons in different roles look at optimization:

Programmers always want to optimize the code. The code isn't optimal, and a lot of speed can be gained from optimizing the code. This usually boils down to optimizing algorithms to be more efficient with either CPU cycles or memory. In contrast to the programmer, the system administrator always wants to tweak the configuration of either the Operating System, the application itself, or some piece of middle-ware in between. Meanwhile, managers always want to optimize the hardware. "Developer time is more expensive than hardware", they quip, so they decide to throw money at faster and more hardware, instead of letting the developer optimize the code.

What none of them realise is that they're all wrong. None of these approaches are any good. When it comes to optimizations, all of the people above are stuck in their own little world. Of course managers just love the fact that programmers "don't understand cost versus benefit", and a nice saying such as "Developer time is more expensive than hardware" has a really nice ring to it. Managers have a high-level view of the application's eco-system, and so they search for the solution in the cheapest component: hardware. Programmers, on the other hand, know the system from a very low-level point of view. And they naturally love the fact that managers don't understand technology. They are intimately familiar with the code of their application, or the database running behind it, and so they know a lot of its weak spots. Of course, they'll assume the optimization is best performed there. The system Systems administrators have limited options either way, so they stick to what they can influence: configuration.

An excellent example of this is a recent post on the JoelOnSoftware blog. I'll recap the main points I'd like to illustrate here:

One of the FogBugz developers complained that compiling was pretty slow (about 30 seconds). [...] He asked if it would be OK if someone spent a few weeks looking for ways to parallelize and speed it up, since we all have multiple CPU cores and plenty of memory. [...] I thought it might be a good idea to just try throwing money at the problem first, before we spent a lot of (expensive and scarce) developer time. [...] so I thought I'd experiment with replacing some of the hard drives around here with solid state, flash hard drives to see if that helped.

Suddenly everything was faster. Booting, launching apps… even Outlook is ready to use in about 1 second. This was a really great upgrade. But… compile time. Hmm. That wasn't much better. I got it down from 30 seconds to … 30 seconds. Our compiler is single threaded, and, I guess, a lot more CPU-bound than IO bound.

This is an excellent example of how a manager would try to solve optimization problems. At the start of the quote we see the typical way a developer would tackle the problem: parallelize and speed up. In other words: low-level optimizations.

Now it turns out Joel was wrong. Solid State disks didn't help at all, since their problem wasn't with disk I/O at all. But that doesn't mean the developer was right either! I like to see it as a kind of Schrödinger's Cat situation: both are wrong, until one is proven right. Why is that? Because they have no idea what the problem is!. All they're doing is guessing away at the problem in the hopes of finding out what exactly will solve it, without having any clue about the actual problem! We can see this quite clearly: after having dismissed disk I/O as the problem, they assume it must be because "our compiler is single threaded, and, I guess, a lot more CPU-bound than IO bound.". Again, they jump to conclusions without knowing what the problem is. So now they might not only waste a lot of time on solid state disks without fixing the problem, but they're about to spend weeks of developer time without knowing if that will fix the problem.

So, here is my point:

The most important thing about optimization is analysis.

You can't fix a problem by simply trying different solutions to see if they work. In order to fix a problem, you have to understand the problem first.

So, please, if you're a developer, don't assume saving a couple of CPU cycles here or there will solve the problem. And if you're a manager, don't assume some new hardware will solve the problem. Do some analysis first. Finding out if disk I/O, memory, CPU cycles or single threading is the problem is really not that hard if you spend a little time thinking about it and benchmarking various things. And in the end, you'll have a much better overview of the situation and the problem, and you'll be able to come up with specific solutions which will actually work.

And that's how you save money.

Run mobile Midlets on your PC

Thursday, February 14th, 2008

In anticipation of my new phone (a Sony Ericsson W910i), I decided to spend some time finding various Java Midlets which I need for the phone. I was looking for a decent calculator, translator, dictionary and a E-book reader. I wanted to try the applications, but since I don't have the new phone yet, I thought "Why not find an emulator on which to run them?". In this post I'll detail my journey into the crazy world of J2EE, Midlets, CLDC, MIDP, J2RE and various other weird mobile Java stuff, and show you how I got the emulator and Midlets to run on my Unix (Ubuntu) machine.

Prerequisites

To be able to emulate anything at all, you'll need to have the J2RE installed. That's the Java 2 Runtime Environment; the basic stuff you need to run Java programs. Under Ubuntu, it's as easy as:

sudo aptitude install sun-java6-jre

Get Sun Java Wireless Toolkit

Next you'll need to fetch and install the Sun Java Wireless Toolkit (S2WTK2, previously known as J2ME: Java Micro Edition). You can download it from:

http://java.sun.com/products/sjwtoolkit/download.html.

(Registration not required, amazingly enough). Scroll down on the page until you see the 'Download' button. That'll take you to the download page where you must accept the license and download the toolkit for your platform.

Automatic installation

To install it, you can try the installer:

sh ./sun_java_wireless_toolkit-2_5_2-linux.bin

-- LICENSE --
Do you agree to the above license terms? [yes or no] yes

Testing /usr/bin/X11/java...

A suitable Java interpreter was detected

0) Use /usr/bin/X11/
1) Specify a path to a Java interpreter directory.
2) Cancel this installation.
Select a choice [0-2]:

The installer detected the wrong path, so you'll have to find out where your actual JRE resides on your disk. Under Ubuntu, this is: /usr/lib/jvm/java-6-sun/jre/bin, so we enter that instead of the detected path:

0) Use /usr/bin/X11/
1) Specify a path to a Java interpreter directory.
2) Cancel this installation.
Select a choice [0-2]: 1

Enter a path to the Java 2 SDK: /usr/lib/jvm/java-6-sun/jre/bin/
/usr/lib/jvm/java-6-sun/jre/bin//java
Testing /usr/lib/jvm/java-6-sun/jre/bin//java...

Please enter a directory into which you would like to install the Sun Java(TM) Wireless Toolkit, 2.5.2 for CLDC.

-- Blah blah blah -- follow the instructions --
Please choose one of the following options:
0) Begin copying files if you are satisfied with the settings  .
1) Cancel the installation.
Select a choice [0-1]: 0
Checksumming...

Extracting the installation files...
./sun_java_wireless_toolkit-2_5_2-linux.bin: 466: /usr/lib/jvm/java-6-sun/jre/bin/jar: not found
Failed to extract files. Installation will stop now.
Please try to install Sun Java(TM) Wireless Toolkit again, or contact wtk-comments@sun.com for assistance.

Manual installation

Chances are, however, that it won't work because it can't find the jar binary:

./sun_java_wireless_toolkit-2_5_2-linux.bin: 466: /usr/lib/jvm/java-6-sun/jre/bin/jar: not found
Failed to extract files. Installation will stop now.

If this happens with you, there's another way to install it:

  • The .bin file is nothing more than a shell script (the automatic installer) with an .zip file attached to it. We'll have to remove the shell script header so we can unzip the file.
  • Open the sun_java_wireless_toolkit-2_5_2-linux.bin in a text-editor which can edit binary files without screwing things up. Vim works nicely.
  • Remove the shellscript in the beginning of the file. Keep all the binary stuff
  • Save the file
  • Create a new directory and cd into it: mkdir jwt; cd jwt;
  • Unpack the .bin file: unzip ../sun_java_wireless_toolkit-2_5_2-linux.bin
  • You can now run stuff from the Wiress Toolkit in the current dir or move it somewhere on your hard disk (i.e. /opt/j2me )

Now try the Wireless toolkit out to see if it works:

~$ /opt/j2me/bin/ktoolbar

You can try out an example Midlet game by running:

~$ /opt/j2me/bin/runmidlet /opt/j2me/apps/Games/bin/Games.jad

The Emulated Phone

foo.png

The Phone emulator should pop up with some options for games which can be run. You can control the emulator with the mouse, or with the keyboard: F1, F2 are the Left and Right soft keys. Normal arrow keys on your keyboard correspond to the arrows of the phone. Enter emulates the middle button.

You can configure the emulated phone by with the /opt/j2me/bin/prefs program. Here you can change things such as the type of phone emulated, etc.

Put files on the phone

Sometimes you'll want to put files on the phone. For instance, an mp3 or whatever. You can do this by copying files to the j2mewtk/2.5.2/appdb/DefaultColorPhone/filesystem/root1/ directory in your home directory. This directory is automatically created when you run the Phone emulator.

Running midlets

Running Midlets on the phone is harder then it should be. In order for the emulator to be able to run Midlets, it needs both a .jar and a .jad file. The Jar file contains the actual application and the Jad file contains a definition file so that the emulator knows how to run the Midlet. Most Midlets only come with a Jar file and not a Jad file however. Fortunately it's quite easy to create one yourself. Here's a script which you can use to automatically create a .jad file from a .jar file:

#!/bin/sh

while [ -n "$1" ]; do
        JAR=$1
        JAD="`basename \"$JAR\" .jar`.jad"
        JAR_SIZE=`du -b "$1" | cut -f1`

        echo -n "Generating \"$JAD\" from \"$JAR\".. "
        unzip -p -x "$1" META-INF/MANIFEST.MF > "$JAD"
        echo "" >> "$JAD"
        echo "MIDlet-Jar-URL: $1" >> "$JAD"
        echo "MIDlet-Jar-Size: $JAR_SIZE" >> "$JAD"
        echo "Done."

        shift
done

Copy-paste the file above into a file named jar2jad.sh and make it executable: chmod 755 ./jar2jad.sh. You can now run:

~$ ./jar2jad.sh foo.jar

In order to create a corresponding .jad file. Now you can run the Midlet by executing:

~$ /opt/j2me/bin/runmidlet ./foo.jad

You can now download .jar midlets and test them out on your PC before actually running them on your phone. Not all midlets will work on the emulator though, since some of them depend on phone specific Java libraries. Some phone manufacturers give out SDK's (System Development Kits) for their phones which you can download and install so you can test Midlets which are specific for certain phones. This will be left as an exercise for the reader though.

Why Ethernet didn't work, the real story

Monday, November 19th, 2007

I was just browsing around on Slashdot a bit, and I found an article on the topic of Token Ring Networks.

We all know that back in the day, Token Ring was considered 'better' than Ethernet because Ethernet would start colliding like mad under heavy (60/70% and higher) loads. This was because there was no central authority on who was allowed to send over the wire with Ethernet, so nodes on the network had to duke it out amongst themselves using Carrier Sense Multiple Access with Collision Detection. The more nodes on the network, the more collisions. Token Ring didn't suffer from the same problem, giving higher possible loads on a network.

But this interesting comment on Slashdot claims something else:

In theory, Ethernet on coax should be stable under heavy load. But in the late 1980s and early 1990s, it wasn't, due to defective design of some widely used interface chips. Here's the actual story. See this note by Wes Irish at Xerox PARC [link dead, so not included]

The worst device was the SEEQ 8003 chip, found in some Cisco and SGI devices. Due to an error in the design of its hardware state machine, it would turn on its transmitter for a few nanoseconds in the middle of an interframe gap. This noise caused other machines on the LAN to restart their interframe gap timers and ignore the next packet, if it followed closely enough. This happened even if the SEEQ chip was neither the sender or the receiver of the packets involved. So as soon as you plugged one of these things into a LAN, throughput went down, even if it wasn't doing anything. A network analyzer wouldn't even see the false collision; this was at too low a level.

This was tough to find. Wes Irish worked on the problem by arranging for both ends of Xerox PARC's main coax LAN to terminate in one office. Then he hooked up a LeCroy digital oscilloscope to both ends. Then he tapped into a machine with an Ethernet controller to bring out a signal when the problem was detected and trigger the oscilloscope. Then, when the problem occured, he had a copy of the entire packet as an analog waveform stored in the scope. This could then be printed with a thermal printer and gone over by hand.

Because he had the same signal from both ends of the wire, the wierd SEEQ interference mentioned above appeared time-shifted due to speed of light lag, making it clear that the interference was from a different node than the one that was supposed to be sending. You could measure the time shift and figure out from where on the cable the noise was being inserted. Which he did.

It took some convincing to get manufacturers to admit there was a problem. It helped that Wes was at Xerox PARC, where Ethernet was born. I went up there to see his work, and once I saw the waveforms, I was convinced. There was much faxing of waveform printouts for a few months, and some vendors were rather unhappy, but the problem got fixed.

So that's why.

I'm not completely convinced that is the real reason why Ethernet didn't perform well under high loads back in the day (these days, switches take care of the problem of high levels of collisions on Ethernet networks), but it does make for an interesting read.

Android

Monday, November 12th, 2007

Android is here.

There's been a lot of rumours about a Google mobile phone. Now, it appears that there is no gPhone (thank god), but there is a Google Mobile Phone Software Development Kit!

The SDK appears to have everything you need to build third-party applications for your mobile phone. The SDK is created in Java, has rich 2D and 3D graphics layers and, naturally, the default Google API stuff such as Google Maps. There's also an emulator that allows you to test your application. Why can't all SDK's be as cool as this one? And the best thing: it's Open Source!

So, here's the homepage; the presentation by Sergei Brin and an overview of the architecture (Part 1, Part 2, Part 3).

Not only is Google providing this SDK for free and as Free/Open Source Software.. they're also offering a total ten million dollars in sponsoring to the best and most original mobile applications built with it! Put that in your pipe and smoke it Apple!

Now, all we need is a phone that runs Android. Are you listening mobile phone builders? Nokia? HTek?? We need a phone that can run Android!

Firefox, IE, Opera and Safary all equally safe?

Thursday, September 13th, 2007

NU.nl reports about a (English) Report about the safety of the web. In it, CA reports:

Browsers are one of the most commonly used applications today. Many people believe that Mozilla Firefox is more secure than Microsoft Internet Explorer, but their vulnerabilities are on par. In the first half of 2007, NIST reported 52 vulnerabilities in Internet Explorer of which half were medium or high severity. And there were 53 vulnerabilities reported in Firefox of which almost half were medium or high severity.

The numbers are climbing. In 2006, 96 vulnerabilities were reported in Internet Explorer and 103 reported in Firefox.

Even less popular browsers have more security holes. More than double the vulnerabilities have been reported in the Opera browser. NIST reports 14 vulnerabilities this year versus seven last year, and more than half of this year vulnerabilities are medium or high severity.

Apple Safari has 19 newly reported vulnerabilities this year nearly twice the number reported last year, and half of them are medium or high severity.

When will researchers understand that the number of vulnerabilities reported / fixed are not a good way to determine how secure an application is? The problem is either that these people don't understand software development, or that these people wish to backup their pre-determined claims with hard evidence, so they start looking at reported vulnerabilities. It doesn't work that way, unfortunately. There are way too many variables not accounted for:

  • First off, where are the sources for their data? They only mention NIST, but no criteria they looked at at all. This immediately invalidates their findings.
  • They look at 'reported' vulnerabilities, but these are third-party reports. Does NIST only reports vulnerabilities listed in the application's release notes?
  • Do these statistics include reported, but unfixed bugs? Firefox maintains an open bug reporting facility where every user can report bugs. Not all of those vulnerabilities may have been fixed. Are those included in the statistics? If so, how can they compare those reports against the reports done on a closed bugtracking system such as IE, Safari and Opera?
  • Where is the proper trend analyses? "In 2006, 96 vulnerabilities were reported". Trend analyses should be done over multiple years, IMHO.
  • What were the severities of the reported/fixed vulnerabilities? For all we know, IE had 100 minor problems that were only exploitable when the moon was full and it was friday the 13th, but Firefox had 50 extremely severe vulnerabilities.
  • What are the sources for the severities? The vendor? Hardly reliable information, as vendors like to downplay their own vulnerability's severity.
  • The report doesn't take in account the user-base of the products. Nobody uses Firefox, Safari and Opera, whereas everybody uses Internet Explorer. That makes it a much bigger target for black-hat exploiters. No, it doesn't say anything about the security of a product from a technical point of view, but it does from a practical point of view.
  • The report mentions, briefly, the security of third-party browser plugins such as Flash, Java, etc. But they make no relation to the different browsers. Firefox has a very easy to install and use Flash / Java blocker. It also has a very good Javascript blocker. Javascript is probably the number one source of vulnerabilities in Firefox. Since it's not installed by default, I can understand they don't focus on this, but at least the security potential for Firefox is higher because of this.
  • No mention is made about ActiveX. ActiveX only works on Internet Explorer and is a HUGE contributor to security vulnerabilities.
  • One of the most important things: Reality! People like to ignore it (which I can understand), but that doesn't mean it doesn't exist. How many vulnerabilities have actually led to exploits in the wild?

In defence of CA, their report doesn't specifically say that Internet Explorer, Safari, Firefox or whatever is more secure than the other. They just imply it. As usual, media outlets are twisting the view on reports in order to make for better news and scare-mongering.

DDoS attack paralyses Estonia

Sunday, September 9th, 2007

Hackers Take Down the Most Wired Country in Europe:

At exactly 11 pm, Estonia was slammed with traffic coming in at more than 4 million packets per second, a 200-fold surge. Globally, nearly 1 million computers suddenly navigated to a multitude of Estonian sites, ranging from the foreign ministry to the major banks. It was a larger-scale version of what had happened to the Postimees, except that the entire country's bandwidth capacity was being squeezed.

The story is a little over the top, there's a lot of speculation and I doubt Estonia is 'the Most Wired Country in Europe', but it's still an interesting read. I wonder if the Europian Union has any plans on how to counter such calamities. Basically all that's needed is a good line of communications via which immediate action can be taken to stop traffic as close to the root as possible, I guess.

RDesktop goodness

Monday, August 13th, 2007

Every now and then, I have to log into a windows machine in order to log expense reports or make a leave request for my work. (The application they use for that at my work doesn't work properly in Firefox. Welcome to 2007.) Fortunately, we've got a big VMWare platform where I can login to a fast virtual Windows 2003 host. Naturally, I use rdesktop for that. There's some cool options to rdesktop that I didn't know about:

First of all, you can automatically log in using the -u, -p and -d options:

rdesktop -u fboender -p F0oB@22000 -d OFFICE win23k.office

You can set the remote desktop geometry using the -g option. That way, you can have a nearly-full-screen remote desktop. For instance, I run at 1280×1024 resolution, and the top menu bar is 24 pixels high, so I create a remote desktop with dimensions of 1280×1000:

rdesktop -g 1280x1000 win23k.office

I also don't like it if rdesktop takes over my window managers keybindings, cause I've got application launchers bound to keybindings such as Win-R (which launches my Run Program application). So I turn off rdesktop's "Take over Keybindings option" using -K

rdesktop -K win23k.office

If all you do is run a single application on the windows machine, for instance Internet Explorer, you can just as well run that straight away using the -s option. This will bypass the default shell and start the application straight away. This means you have no desktop window underneath your application and no windows taskbar at the bottom of the rdesktop window. Since Windows programs come with their window decorations (titlebar, close buttons, etc), you can turn off the ones for your Window manager using -D:

rdesktop -s "C:\\Program Files\\Internet Explorer\\iexplore.exe" -D w2k3.office

That starts an Internet Explorer window as if it's running on your local computer. Unfortunately, this means you no longer have a minimize button. But that's what the -S option is for. This enables the -D option and changes the behaviour of the remote minimize button to minimize the local rdesktop window instead of the remote window. You have to specify a button-size with the -S option, because the rdesktop client has to guess where the buttons are in the remote application. 18 is the default size for default windows themes.

rdesktop -S 18 -s "C:\\Program Files\\Internet Explorer\\iexplore.exe" -D w2k3.office

Use the -T option to set the local window's title, if you're starting more than one different remote application at the same time:

rdesktop -T "Internet Explorer 7.0" -S 18 -s "C:\Program Files\Internet Explorer\iexplore.exe" -D w2k3.office
rdesktop -T "Photoshop" -S 18 -s "C:\\Program Files\\Adobe\\Photoshop\\ps.exe" -D w2k3.office

Of course, even cooler would be if you installed the SeamlessRDP component on your Windows server, so you can true single remote applications on your desktop, just like X11 supports.

Finally, the very cool -r option, which allows you to forward local devices, printers, cdroms and directories to the remote server. It also allows you to redirect remote sound to the local machine.

rdesktop  -r disk:home=/home/todsah w2k3.office

This will make my local home directory available as a special share on the remote Windows machine so that I can access my files from the remote machine.

That's about it for cool rdesktop stuff. Remember! Use sparingly.. it's still windows, right?

Jailing SFTP/SCP

Thursday, August 9th, 2007

Here's how to set up a jailed / chrooted SFTP/SCP environment for a single user:

Note: This is a little specific for Debian in some places, but it should work for other distributions too. You may need to tweak the jailkit configurations in /etc/jailkit/jk_init.ini a bit.

Get jailkit (http://olivier.sessink.nl/jailkit/index.html#download). Jailkit is an awesome tool that'll allow you to set up minimal jails by inspecting which libs are used by binaries and copying them, the binaries and some other directories to a seperate dir, which can be used as a chrooted environment.

Get Jailkit and install it:

$ wget http://olivier.sessink.nl/jailkit/jailkit-2.4.tar.bz2
$ tar -xjf jailkit-2.4.tar.bz2
$ cd jailkit-2.4
$ ./configure
$ make
$ make install

Now, create a new normal user like you would normally do. In a moment, we'll use jailkit to move this user to the jail.

$ adduser --disabled-password public

Set up the jail. You can't do this in /home! (You can move everything to /home later if you want to).

$ mkdir /jail
$ chown root:root /jail
$ chmod 755 /jail
$ jk_init -v -j /jail/public/ sftp scp jk_lsh

This copies all the library files sftp and scp need to /jail/public. If you look at /etc/jailkit/jk_init.ini, you'll see sections there for the sftp, scp and jk_lsh programs. They include some directories to include in the copy, etc. jk_lsh is a minimal, restricted shell for the jail environment that restricts what commands can be run in the jail environment. In this case, it will limit commands to sftp and scp.

Now, we move the public user to the jail:

$ jk_jailuser -m -j /jail/public/ public

Edit the /jail/public/etc/jailkit/jk_lsh.ini file and add which program the jailed user may run. In this case, scp and sftp-server.

[public]
paths= /usr/bin, /usr/lib/
executables= /usr/bin/scp, /usr/lib/openssh/sftp-server

Just to be sure, check if the executables exist:

$ ls /jail/public/usr/lib/openssh/sftp-server
$ ls /jail/public/usr/bin/scp

If you want, move the /jail/public to /home/ and edit /etc/passwd to reflect this change.

$ mv /jail/public /home/public
$ vim /etc/passwd

and change the homedir for user public from /jail/public/./home/public to: /home/public/./home/public (Yes, that's correct).

$ rmdir /jail/

Done.

If you want to add public key authentication:

$ mkdir /home/public/home/public/.ssh
$ chown public:public /home/public/home/public/.ssh
$ vim /home/public/home/public/.ssh/authorized_keys2

Add the public key to the authorized_keys2 file.

You can place directories from outside the jail inside the jail using mount:

$ mount --bind /storage/sound/mp3/ /jail/public/home/public/mp3/

The result?

[todsah@jib]~$ sftp public@sharky
Connecting to sharky...
Password:
sftp> ls
mp3
sftp> ls /
/dev   /etc   /home  /lib   /usr
sftp> ls mp3
mp3/10 CC                                                             mp3/Aeternus
mp3/After Forever                                                     mp3/Air
mp3/Alborada                                                          mp3/Alter Bridge
mp3/Aphix Twin                                                        mp3/Apocalyptica
mp3/Arch Enemy                                                        mp3/Autumn
mp3/Bachmann Turner Overdrive                                         mp3/Beethoven
etc.

There's tons of other cool stuff you can do with Jailkit. Check out the HowTo's on the Jailkit homepage.

Oh, and the size?:

[root@sharky]/home# du -hs public/
4.1M    public/

Update! Important!

Remember that you need to regularly do a jk_update -j /jail/public/ to update the files in the jail! Remember that a jail has files (libraries, executables) that are copies of the main system. So any security fixes in files in the main system aren't reflected in the jail until you do an jk_update!

Firefox extensions I'm using

Monday, July 9th, 2007

Here's a quick list of the Firefox extensions I'm currently using:

  • CookieSafe
    Deny/allow cookies per-site.
  • DOM Inspector
    Inspect the DOM tree. Useful for debugging Javascript stuff.
  • Download statusbar
    No more Downloads pop-ups. This extension puts all your downloads in a bar in the bottom of the window.
  • Firebug
    This extension shouldn't be missing from your firefox plugins list if you're a web developer. It does too many useful things to list here. Just get it.
  • FireFoxMenuButtons
    Add menu-buttons to the Customize Toolbar for often-used menu items.
  • FlashBlock (disabled)
    Block Flash from playing unless you click on the flash movie. This helps a lot if your browser crashes a lot due to Flash. My firefox never crashes, unless I visit a site that requires Flash.
  • HTML Validator
    Shows a little icon in your status bar that shows if the current site validates as valid HTML. Doesn't require an internet connection but uses HTML Tidy.
  • Link evaluator
    Check if all the links on the current page are valid.
  • Live HTTP Headers
    Spy on the headers sent and received by Firefox.
  • Media Player Connectivity
    Play media in stand-alone movie players. Ideal for Linux where media players can't be embedded.
  • NoScript
    Disable/Enable Javascript per-site. Good for security.
  • ScrapBook
    Keep offline copies of websites.
  • Tab Mix Plus
    Extra Tab settings.
  • URLParams
    Allows web developers to easily modify HTML forms (including hidden fields). Ideal for quick and easy testing of web forms.
  • View Cookies
    Display cookie information in the View Page Info dialog.
  • View dependencies
    View all Link Rel elemens in a page, such as images, CSS, Javascript, etc.
  • View Source With
    Edit Forms and stuff in your favorite editor. Also doubles as 'Open with…' functionality.
  • Web Developer
    Handy tool with lots of stuff for web deverlopers.