procmail gpg - zweryfikuj podpis

0

Czy istnieje przepis na procmail, którego mogę użyć do zweryfikowania podpisu pgp? Prawie jak gpg --verify. Patrzyłem na pgpenvelope, ale nie muszę tego sprawdzać w żadnym kliencie pocztowym.

deadlisting
źródło

Odpowiedzi:

0

To rozwiązanie działało świetnie. Jest trochę stary, ale nie miał z tym żadnych problemów. https://www.w3.org/2004/07/pgp-whitelist.html

Wymagania

Aby skonfigurować ten system białej listy, potrzebujesz:

działające środowisko procmail, skonfigurowane do filtrowania poczty przychodzącej na tym samym komputerze co procmail, implementacja PGP; zakładamy, że od teraz jest to gnupg, ale system powinien być przystosowany do innych klientów, a także do zestawu kluczy osób, którym ufasz, zaimportowanych do środowiska PGP; za pomocą gnupg zaimportowałbyś klucz za pomocą gpg --recv-key key_id, pod warunkiem, że masz skonfigurowany serwer PGP do pobierania kluczy z Konfiguruj

System, który konfigurujemy, wykonuje następujące działania:

w przypadku każdego otrzymanego e-maila sprawdza, czy nadawca podany w nagłówku From znajduje się na naszej zaufanej liście (.pgp-biała lista), jeśli tak, sprawdza, czy wiadomość jest podpisana, a jeśli tak, to czy jest poprawna (z skrypt mailverify), jeśli tak, dodaje nagłówek X-Biała lista: Tak, po upewnieniu się, że wiadomość przychodząca nie ma takiego nagłówka Skrypt mailverify użyty do wykonania czeku można pobrać z serwera publicznego W3C CVS. W tym miejscu musisz zmienić połączenie do klienta PGP, jeśli nie jest wywoływany jako gpg.

Zakłada się, że biała lista .pgp znajduje się w twoim katalogu domowym; zmień ścieżkę w poniższej zmiennej PGP_WHITELIST, jeśli tak nie jest. Jego zawartość to lista adresów e-mail (po jednym w wierszu), którym ufasz i które chcesz umieścić na białej liście, jeśli otrzymasz od nich odpowiednio podpisaną pocztę.

Odpowiednie reguły procmail, które należy dodać do pliku konfiguracyjnego .procmailrc, znajdują się poniżej; należy je dodać przed konfiguracją identyfikacji spamu, jeśli robisz to również przy użyciu procmaila.

# .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/
}

Skrypt Perla, który jest mailverify. Dostosuj odpowiednio foldery MAILDIR.

#!/usr/bin/env perl
# File Name: mailverify
# Maintainer: Moshe Kaminsky <[email protected]>
# 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 <[email protected]> - Copyright (c) 2003

=head1 LICENSE

This program is free software. You may copy or 
redistribute it under the same terms as Perl itself.

=cut

Uznanie dla Mosze.

deadlisting
źródło