blosmail.pl

pemungkah on 2004-11-08T20:51:05

My other weblog is Blosxom-based. I find I don't update it as often as I could/should, mostly because it's a pain to update - log in to the remote server, write the entry, save it ... it just loses the immediacy for me. I've tried a couple of the Bloxsom plugins to make it easier, but I haven't been happy with any of them.

I saw blosmail.pl go by on del.icio.us today. It's a little Perl script that parses a mail message and posts it to your Blosxom weblog. Immediately alarms began to go off - the EMUSIC-L weblog isn't exactly BoingBoing in terms of traffic, but I could just see my poor little weblog getting spammed up the wazoo. Okay, so there's a password-protection feature. You put the password in the mail and send it. This didn't strike me as a whole lot better - I wanted something that would be easy to do, but hard enough to crack that it really wouldn't be worth it.

So the following code code does an MD5 hash of the body of the message with a secret string stored on the server. If the hashes match, the post is accepted. At the moment, it still takes a little more work than I'd like: I have to run the message text through an external script and then paste the resultant hash back into the message. What this really wants is a drag-and-drop applet (probably doable with Platypus) or a full-fledged OS X service.

Anyway, here's blosmail-md5.pl. Update: After seeing this happen to someone, I separated the blosmail config directory from the Blosxom data directory. (Yes, I did drop them a note.)

#!/usr/bin/perl -w

# blosmail # Allows you to post (and modify) blosxom entries via email # Version 0+1a # DJ Adams June 2002

# See http://www.pipetree.com/testwiki/Blosmail # Changes # 0+1b fixed secret mechanism # 0+1a added -secret parameter # 0+1 original version # # Modified 8-Nov-2004 by Joe McMahon # - folded in Doug Alcorn's 'category and title from subject' extension # - added security via MD5 hash of content

use strict; use File::Path; use File::Temp qw/ tempfile /; use FileHandle; use CGI qw/:standard :debug/; use Digest::MD5;

# --- Configurable variables -----

# Where are my blog entries kept? my $datadir = "/Users/joe/blosxomdata"; my $configdir = "/Users/joe/blosmail_config";

# --------------------------------

$datadir = "$datadir/".param('-blog') if param('-blog'); my $fh = new FileHandle;

# Get the list of valid email addresses my @validEmail = $fh->open("< $configdir/blosmail.dat") ? (<$fh>) : (); chomp @validEmail;

# Read in whole mail and split into headers and body my ($headers, $body); { local $/ = undef; ($headers, $body) = split("\n\n", , 2); }

# Check MD5 sums: combine the local copy of the password and the post text # and sum them. Should match the sum that appears on the first line. if (param('-sum')) { (my $incoming_sum, $body) = split(/\n/, $body, 2); chomp $incoming_sum; $fh->open("< $configdir/secret.dat") or die "No local secret\n"; my $local_secret = <$fh>; chomp $local_secret; my $ctx = Digest::MD5->new(); $ctx->add($local_secret.$body); my $local_sum = $ctx->hexdigest; die "Incorrect checksum" if $local_sum ne $incoming_sum; }

# Check it's from a valid email address my ($from) = $headers =~ /^From:\s.*?<([^>]+)>.*?$/m; die "Entry from invalid email address" unless grep(/$from/, @validEmail);

# Determine filename and write entry my ($category, $title) = ($headers =~ /^Subject:\s+BLOG\/([^\s]*)\s*(.*)$/m) ? ($1, $2) : ""; die "No title supplied\n" unless ($title);

unless (-d "$datadir/$category") { mkpath ("$datadir/$category", 0, 02775) or die "Can't create '$category' directory, $!\n"; } my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year +=1900; $mon += 1; my $filename; ($fh, $filename) = tempfile("${year}${mon}${mday}XXXXXX", SUFFIX => ".txt", DIR => "$datadir/$category", UNLINK => 0); print $fh $title, "\n"; foreach my $line (split /\n/, $body) { last if ($line =~ /^--/); print $fh $line, "\n"; } $fh->close;

chmod 0644, "$datadir/$filename";