#!/usr/bin/perl # PGP signatures for ezmlm # (c) Alex Efros my $maillist = $ARGV[0]; # email & private key my $signpass = $ARGV[1]; # private key password $ENV{GNUPG_HOME}= $ARGV[2]; # keyrings directory $ENV{EZMLM_PGP_PID} = $$; # используется в .muttrc-ezmlm $ENV{TERM} = "linux"; # для mutt на /dev/vc/60 $ENV{LANG} = "ru_RU.koi8r"; my $mbox = "/tmp/ezmlm-pgp.mbox.$$"; # temp file with message my $verify = "/tmp/ezmlm-pgp.verify.$$"; # temp file with verify message my $good = `gettext -d gnupg -s 'Good signature from "' | tr -d '"\\012'`; warn("ezmlm-pgp: bad maillist"), exit 100 if $maillist !~ /^[\w.-]+\@[\w.-]+$/; warn("ezmlm-pgp: bad GnuPG dir"), exit 100 if not -d $ENV{GNUPG_HOME}; # Сохранить письмо во временный файл в формате unix mailbox open my $F, "> $mbox" or die "open: $!"; print $F "From $maillist Sat Jan 1 00:00:00 2000\n", ; close $F or die "close: $!"; # Проверить подпись (MIME или PLAIN) и сохранить результат в $sig safe_system("/usr/bin/mutt -n -F /etc/qmail/alias/.muttrc-ezmlm -f $mbox -e". " 'push Q'". " /dev/null 2>&1"); my $sig = `/bin/cat $verify 2>/dev/null`; my $encrypted; if ($encrypted = $sig =~ /decryption failed: secret key not available/) { # Повторить проверку подписи если письмо зашифровано safe_system("/usr/bin/mutt -n -F /etc/qmail/alias/.muttrc-ezmlm -f $mbox". " -e 'push $signpass". "Q' /dev/null 2>&1"); $sig = `/bin/cat $verify 2>/dev/null`; } if ($sig !~ /\Q$good\E/) { # письмо не подписано или подпись не может быть проверена warn "bad/unknown/absent PGP signature\n"; exit 100; } elsif ($sig =~ /\Q$good\E.*?\Q$maillist\E/) { # письмо уже подписано maillist-ом, продолжить обработку exit 0; } else { if ($sig =~ s/^(?!gpg: ).*\n$//mg) { # при PLAIN подписи удалить копию письма, которую вернул gpg open my $F, "> $verify" or die "open: $!\n"; print $F $sig; close $F or die "close: $!"; } # письмо от юзера, подписанное # [дешифровать], подписать его maillist-ом и перепослать себе еще раз # если подпись юзера была в MIME, то она удаляется, если PLAIN - остается # к письму аттачится информация об исходной подписи юзера safe_system("/usr/bin/mutt -n -F /etc/qmail/alias/.muttrc-ezmlm -f '$mbox'". " -e 'set pgp_sign_as=\"$maillist\"'". " -e 'push ".($encrypted?$signpass."":""). ".$verifyfs". "".($encrypted?"":$signpass."")."q'". " /dev/null 2>&1"); exit 99; } END { unlink $mbox; unlink $verify; } sub safe_system { # mutt зависает на PLAIN/encrypted my $chield; $SIG{ALRM} = sub { kill 15, $chield }; alarm 3; $chield = fork() or exec "exec $_[0]"; wait; alarm 0; }