Tuesday, January 27, 2009

Playing with Perl :P

I always had problems in reading my RSS feeds because I never found any good RSS reader (Google things are not an option here). The fact is: I’m not able to read my friends – or enemies – feeds, but I'm a good email reader so I decided to search a way to send the feeds to my email so, I will be able to read them.

I found a nice toy to do that, it is called: rss2email. Really nice toy. I just placed it to run on my server and it started to deliver my content.

After one week using it, I saw that I didn't subscribe any new feed. Imagine yourself logging in a server to add a new RSS feed... nah too complicated. Too much work for me.

So I decided to create a new mail alias to receive commands and process them by its procmail rules. Well ok, what about the security? And if that MTFK friend decide to clean up my entire feeds? That is why I decided to verify my gpg signature before process the commands and for that a combination of procmail rules and my cute Perl script is amazing.

Here goes my Perl script and enjoy:
#!/usr/bin/perl
#
# Copyright (C) 2009 Felipe Zimmerle
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#

# Config.
$ Config {'trusted'} = 'E8B11277';
$config{'debug'} = 1;
$config{'rss2email'} = '/your/path/to/rss2email/rss2email.py';
$config{'dat'} = '/your/path/to/rss2email/feeds.dat';
$config{'mailto'} = 'your@mail.something';
$config{'sendmail'} = '/usr/sbin/sendmail';
$config{'label'} = '/your/path/to/labels.txt';
$config{'mail'} =<<EOT;
To: $ config {'mailto'}
From: RMO Report <felipe-rss\@zimmerle.org>
Subject: rmo report

RMO Results:

RESULTS

EOT

# Do not edit above this line.
use IPC::Open3;
use IO::Handle;
use Encode;

undef $/;
my $mail = <>;
$mail =~ s/=(\n|\r|\n\r|\r\n)//gom;
$mail =~ s/=3D/=/gom;
$mail =~ s/=20/ /gom;

my ($ IN, $ OUT, $ ERR) = (IO :: Handle-> new (), IO :: Handle-> new (),
IO :: Handle-> new ());
open3 ($ IN, $ OUT, $ ERR "gpg") | | die "Unable to run: $ \ n";
print $IN $mail;
close($IN);

my $from,@cmd,$results,$pr,$ops;

# Parser the commands.
my $o = <$OUT>;
$o = ~ s / ^ add (\ "[A-z0-9_. -] + \" | [A-z0-9_. -] +) (. *) / @ {[Eval {$ pr + +; $ cmd [@ cmd] =
["add", "$2", "@{[eval {$a = $1; $a =~ s@^(\")(.*)(\"$)@$2@; $a;}]}"] }]}/gome;
$o = ~ s / ^ (the | delete) ([0-9] +) / @ {[eval {$ pr + +; $ cmd [@ cmd] = ["delete", "$ 2"] if $ pr 1 }]}/gome;
$o = ~ s / ^ list / @ {[$ cmd [@ cmd] = ["list"]]} / gome;
close($OUT);

# Check signature.
my $ e = <$ ERR>;
$from = $1 if $e =~ m/.*key ID ([A-z0-9]+)(\n|\r|\n\r|\r\n)gpg: Good signature from.*/m;
close($ERR);

die "Wow a hacker:\n$mail" if $from ne $config{'trusted'};

foreach my $c (@cmd) {
my $ config = $ c_ {'rss2email'}. "". $ Config {'dat'}.
" " . $c->[0] . " " . $c->[1];
$results .= "Command: $c_\n" . `$c_` . "\n";
`echo $c->[2],$c->[1] >> $config{'label'}` if $c->[0] eq "add";
}
$results .= "\nDelete request is just welcome if its come " .
" alone. $ops delete" .
"s"?"":$ops>1 . " ignored.\n" if ($ops > 0);

$config{'mail'} =~ s/RESULTS/$results/;

open (S, "| $ config {'sendmail'} t $ config {'mailto'}") or die "."
"Unable to run sendmail: $!\n";
print S $config{'mail'};
close(S);

I really love Perl. Amazing, just few lines and my problem was solved ;P