A graphical MD5 validator

Sometimes, in technology, you just go around in a circle. Back in 2007, I was cruising Ubuntu Forums and found this thread that intrigued me. A lady was looking for a gui that would give an MD5 hash for a file. I played with some code to help her then, and subsequently forgot about it as I started using the excellent Download Them All Firefox extension, which includes checking files downloaded from the Web against any number of verification codes, including MD5.

So last weekend I started looking at lightweight Debian-based distributions to load on my big USB stick to run as a Live USB. I found one I wanted to try (PureOSlight) but the website only gave an MD5 of the ISO image, and a link to a third party website where I could get  a torrent file so to download the image via BitTorrent. Playing with unknown software is risky enough, but in this situation the original author has no direct control over the ISO image I was going to fetch. So verifying against his MD5 hash was the only safe way I could work — and my BitTorrent client, Transmission, didn’t have a hash-checking feature as far as I could see.

So while Transmission was getting pieces of my image from four different unknown places, I thought, it would be nice to get some stand-alone hash checking software. I checked out GtkHash from Ubuntu’s repository and thought it was quite nice, but it was missing two features I wanted. First, I saw no place where I could paste the hash the author provided, so I was going to have to eyeball-compare it against the one calculated by GtkHash from the image file. Man, I’m just too picky sometimes. Also, GtkHash won’t take a filename as an argument, so I couldn’t use it from a file manager. I wanted to be able to use it directly from Nautilus by finding the image file, right-clicking, choosing the Open With feature, then give me a text box to paste the hash into. Then it would calculate the MD5 of the file, and have the computer do the comparison.

So someone must have done it, and Googling around didn’t show any packaged software like that, but I did find my old forum thread from years ago! Since I have a few days off, and am procrastinating on my tax return, I just could not leave this unfinished. Now that I’ve got it to a working point, though, I still haven’t got to play with what I originally downloaded.

I’m releasing this under the MIT license, so you can do what you want with it, except sue me about it, but I would appreciate your posting suggestions for improvement here. This is alpha-quality at this point, but it does do the job.  To install, paste the text below  it into a file named “md5compare” (/usr/local/bin is an appropriate place), and make it executable for all users (sudo chmod +x /usr/local/bin/md5compare). Technical notes from writing this little accessory appear after the code:

#! /bin/bash
# md5compare
# A graphical MD5 validator
# https://jimcooncat.wordpress.com/2011/03/09/a-graphical-md5-validator/
# Released under MIT license
# http://www.opensource.org/licenses/mit-license.html
# Usage: md5compare [filename]
# Can accept a filename for an argument, for
# example to use with a file manager's "Open with" feature,
# or will show a file selector if none is given.
Commandname=$(basename $0)
SupposedMD5=$(zenity --entry \
  --text "Enter MD5Sum that file is supposed to be" \
  --title $Commandname)
if [ $# -gt 0 ]; then
  Filename=$(zenity --file-selection  --title $Commandname)
Tempfile=$(tempfile --prefix="md5-" --suffix=".list")
SpaceChar=" "
echo "$SupposedMD5$SpaceChar$SpaceChar$Filename" > $Tempfile
Result=$(md5sum -c $Tempfile 2>&1 | \
  tee >(zenity --progress --text "Calculating MD5sum" \
    --title $Commandname --pulsate --auto-close) )
rm $Tempfile
zenity --info --text "$SupposedMD5\n $Result " --title $Commandname

Some things I ran into while writing this:

  1. $0 is the full pathname to this script, so I set each window’s title to $(basename $0) in case you come up with a better name for it than md5compare.
  2. I have no real error checking in this script, it would be smart to verify that the hash pasted in by the user is verified to be the correct format before going continuing.
  3. In a full-featured version, it would be nice if the file-picker (displayed if no filename is passed to the script) defaulted to the directory where the user normally downloads their files. We’d need to store that preference in their /home.
  4. The tempfile command is very nice to use to give a unique name to a temporary file. I’m using it here for input to the md5sum command. Initially, I wanted to use a prefix of “md5command”, however it truncated my prefix after the fifth character. That’s kinda lame.
  5. The md5sum input file format is strange. It takes a file formatted with two spaces between the hash and the filename. For some reason (I am a bash noob), when I generated the file using the echo command initially, my two spaces in the script became only one in the file. So I assigned a space character to a variable and it worked properly with the code above.
  6. When running the md5sum command I wanted to show the user any error messages produced by it, so I used the “2>&1” phrase. This redirects stderr to stdout, so the final dialog will show any error messages. The message isn’t really pretty, but it is informative.
  7. While md5sum is churning against a large ISO image file, I piped the output to zenity’s progress dialog using tee. Otherwise, the user thinks that nothing is going on or the script aborted as the last dialog box would be closed. The pulsate feature doesn’t work though, since md5sum doesn’t generate any output while it’s crunching through a single large file. However, it serves the purpose, as the progress box closes when the md5sum command finishes.
  8. The final dialog box could be a bit more informative, especially for a new user.

Your thoughts and suggestions, please!


Packaging Configuration Files?

Dear lazyweb, I have a question about Debian Packaging (which also extends to Ubuntu and related distros) that would allow me to install a server with custom configurations. Here’s an example of what I’d like to do with the venerable openssh-server package, where I want to install an ssh server on a non-standard port.

custom-openssh-server (metapackage)
depends: custom-openssh-server-config, openssh-server

custom-openssh-server-config (adds non-standard port)
contains: /etc/ssh/sshd_config

openssh-server (straight from the official repo)

The idea here is to install our custom config before installing the package we want. Good packages are not supposed to overwrite configuration files.

So when we add our metapackage to a preseed (building a computer from scratch), it would automatically do the right thing. If openssh gets a security update, version numbering would work correctly.

Since we could have some sensitive information in the config files, we could use an ssh repository with apt, or at a minimum only make our personal repository only available on the local network.

Can anyone explain the downsides to this approach?