procmail gpg - Signatur überprüfen

468
deadlisting

Gibt es ein Rezept für procmail, mit dem ich eine PGP-Signatur verifizieren kann? Fast wie gpg --verify. Ich habe mir pgpenvelope angesehen, aber ich muss das in keinem Mail-Client nachsehen.

0

1 Antwort auf die Frage

0
deadlisting

This solution worked great. Its a bit old but had no issues with it. https://www.w3.org/2004/07/pgp-whitelist.html

Requirements

To set up this whitelist system, you need:

a working procmail environment, set up to filter your incoming email on the same computer as procmail, an implementation of PGP; we assume it is gnupg from now on, but the system should be adaptable to other clients as well the set of keys of person you trust imported in your PGP environment; with gnupg, you would import a key using gpg --recv-key key_id, provided that you have a configured PGP server to get the keys from Set up

The system we're setting up does the following actions:

for any email it receives, it checks if the sender given in the From header is in our trusted list (.pgp-whitelist) if it is, it checks whether the mail is signed and if it is, whether it is correctly so (with the mailverify script) if it is, it adds a X-Whitelist: Yes header, after having made sure that the incoming mail didn't have such a header The mailverify script used to make the check can be downloaded from W3C CVS Public server. This is where you would need to change the call to your PGP client if it is not invoked as gpg.

The .pgp-whitelist is assumed to be in your home directory; change the path in the PGP_WHITELIST variable below if it isn't so. Its content is a list of email addresses (one per line) that you trust and want to be whitelisted if you receive properly signed mail from them.

The relevant procmail rules to add to your .procmailrc configuration file are below; they should be added before your set up for identifying spam if you do so using procmail too.

# .procmailrc - Check whitelist PGP_WHITELIST=$HOME/.pgp-whitelist #looking from spam, but blessing sender from my white list # by setting a X-Whitelist header # First, removing fake headers :0 fwh * ^X-Whitelist | formail -IX-Whitelist # checking for people with a trusted PGP key FROM=`formail -XFrom: | formail -r -xTo: | tr -d ' '` PGP_OK=`$HOME/mailverify 1>/dev/null && echo 1` :0 * ? egrep -q "$FROM" $PGP_WHITELIST * ? test -n "$PGP_OK" { :0 fwh | formail -a"X-Whitelist: Yes" :0: $MAILDIR/good/ } :0 fwh * !^X-Whitelist: Yes { :0: $MAILDIR/bounce/ } 

Perl script that is mailverify. Tweak MAILDIR folders accordingly.

#!/usr/bin/env perl # File Name: mailverify # Maintainer: Moshe Kaminsky <kaminsky@math.huji.ac.il> # Original Date: September 30, 2003 # Last Update: September 30, 2003 # http://mirror.hamakor.org.il/archives/linux-il/att-5615/mailverify ########################################################### use warnings; use integer; BEGIN { our $VERSION = 0.1; # analyze command line use Getopt::Long qw(:config gnu_getopt); use Pod::Usage; our $opt_help; our $opt_man; our $opt_version; our $Gpg; our $Tolerant; GetOptions('gpg=s' => \$Gpg, 'tolerant!' => \$Tolerant, 'help', 'version', 'man'); pod2usage(1) if $opt_help; pod2usage(-verbose => 2) if $opt_man; print "$0 version $VERSION\n" and exit if $opt_version; $Gpg = '/usr/bin/gpg --batch --verify' unless $Gpg; } use File::Temp qw( tempfile ); my $PrevField = ''; # process the header while (<>) { next if /^From /o; last if /^$/o; if (/^([\w-]+): (.*)$/o) { $Header{$1} = $2; $PrevField = $1; } else { $Header{$PrevField} .= $_; } } # check that the message is signed $Str = $Header{'Content-Type'}; @Parts = split /;\s+/, $Str if $Str; if (not $Str or $Parts[0] ne 'multipart/signed') { # the message is not multipart/signed, but might still be cleartext # signed. Depending on --tolerant, we may pass the rest of the message to # gpg directly print "Message not signed\n" and exit -1 unless $Tolerant; open GPG, "|$Gpg" or die "Can't open pipe to gpg ($Gpg): $!"; print GPG <>; close GPG; exit $? >> 8; } # the boundary string signals the boundary between two attachments $Boundary = $1 if $Parts[3] =~ /^boundary="(.*)"$/o; # go to the start of the message while (<>) { last if $_ eq "--$Boundary\n"; } # read the message, excluding the last (empty) line while (<>) { last if $_ eq "--$Boundary\n"; push @Message, $_; } pop @Message; # read the sig while (<>) { last if /^-----BEGIN PGP SIGNATURE-----$/o; } { do { push @Sig, $_; last if /^-----END PGP SIGNATURE-----$/o; } while (<>); }; # here comes the funny part: replace \n by \r\n $_ = join '', @Message; s/(?<!\r)\n/\r\n/g; # write everything to files my ($MsgFH, $MsgFile) = tempfile; print $MsgFH $_; my $SigFile = "$MsgFile.asc"; open SIGFH, ">$SigFile" or die "can't open $SigFile: $!"; print SIGFH @Sig; close $MsgFH; close SIGFH; # run gpg print `$Gpg $SigFile`; # clean up unlink $MsgFile, $SigFile; # exit with the status of gpg exit $? >> 8; __DATA__ # start of POD =head1 NAME mailverify - verify the pgp signature of a mime signed mail message =head1 SYNOPSIS B<mailverify> B<--help>|B<--man>|B<--version> B<mailverify> [B<--gpg=I<gpg command>>] [B<--(no)tolerant>] [I<mail file>] =head1 OPTIONS =over 4 =item B<--gpg=I<gpg command>> The command to run to do the actual checking. The default is S<C</usr/local/bin/gpg --batch --verify>>. It is called with one argument, which is the name of the file containing the signature. If B<--tolerant> is used, it may also be called with the whole message on the standard input. =item B<--(no)tolerant> Normally (with B<--notolerant>), if the Content-Type is not C<multipart/signed>, B<mailverify> decides that the message is not signed, and exits with status -1. With this switch, the message is passed to I<gpg> (or whatever was specified with the B<--gpg> option) as is. This way, clearsigned messages can be verified with the same command. =item B<--help> Give a short usage message and exit with status 1 =item B<--man> Give the full description and exit with status 1 =item B<--version> Print a line with the program name and exit with status 0 =back =head1 ARGUMENTS If an argument is given, it is treated a file containing an e-mail message to verify, but more common is to read the message from stdin. =head1 DESCRIPTION This script verifies the pgp signature of files whose signature appears as an attachment (Content-Type C<multipart/signed>). If B<--tolerant> is used, it will also verify clearsigned messages. The usage is basically to pipe the mail to this program. =head1 EXIT STATUS If the message is not of type C<multipart/signed>, and B<--tolerant> is not given, the exit status is -1. In any other case, it is the exit status of the I<gpg> command. =head1 SEE ALSO I<gpg(1)> =head1 BUGS Probably plenty, since I don't read any RFCs. Works with all cases I checked, though. =head1 AUTHOR Moshe Kaminsky <kaminsky@math.huji.ac.il> - Copyright (c) 2003 =head1 LICENSE This program is free software. You may copy or redistribute it under the same terms as Perl itself. =cut 

Kudos to Moshe.