scratch/verify
changeset 18 4ba3303aae86
parent 17 e65ad1481966
child 20 c1810f067e5d
equal deleted inserted replaced
17:e65ad1481966 18:4ba3303aae86
     1 #! /usr/bin/perl
       
     2 
       
     3 use 5.010;
       
     4 use strict;
       
     5 use warnings;
       
     6 use File::Temp;
       
     7 use GnuPG;
       
     8 use autodie qw(:all);
       
     9 
       
    10 use blib;
       
    11 use Message::2822;
       
    12 
       
    13 umask(077);
       
    14 my $dir = File::Temp->newdir();
       
    15 
       
    16 my $signed = Message::2822->new(file => shift // "ex/mails/signed");
       
    17 
       
    18 # output the original message if not 'multipart/sign'
       
    19 my ($content_type) = ($signed->header_lines(qr/^content-type/i) =~ /\s+(\S+)/i);
       
    20 unless ($content_type =~ /multipart\/signed/i) {
       
    21     print $signed->header_lines, "\n";
       
    22     print $signed->orig_body;
       
    23     exit 0;
       
    24 }
       
    25 
       
    26 my ($boundary) =
       
    27   ($signed->header_lines(qr/^content-type/i) =~ /boundary=['"](.*?)['"]/);
       
    28 
       
    29 open(my $body, "+>$dir/body");
       
    30 print {$body} $signed->orig_body;
       
    31 seek($body, 0, 0);
       
    32 
       
    33 # cut the message
       
    34 open(my $message, "+>$dir/message");
       
    35 my $last_line = "";
       
    36 while (<$body>) {
       
    37     last if ($last_line =~ /^\s+$/ and /^--\Q$boundary\E/);
       
    38     next if (/^--\Q$boundary\E/);
       
    39     s/\r?\n/\r\n/g;
       
    40     print {$message} $last_line;
       
    41     $last_line = $_;
       
    42 }
       
    43 
       
    44 # cut the signature
       
    45 open(my $signature, "+>$dir/message.sig");
       
    46 my $in_sign = 0;
       
    47 while (<$body>) {
       
    48     if (/^-----BEGIN\s+PGP\s+SIGNATURE-----$/ or $in_sign) {
       
    49         if (/^-----END\s+PGP\s+SIGNATURE-----$/) {
       
    50             $in_sign = 0;
       
    51             print {$signature} $_;
       
    52         }
       
    53         else {
       
    54             $in_sign = 1;
       
    55             print {$signature} $_;
       
    56         }
       
    57     }
       
    58 }
       
    59 
       
    60 seek($message,   0, 0);
       
    61 seek($signature, 0, 0);
       
    62 
       
    63 # ask GPG to verify it…
       
    64 my $gpg = new GnuPG(homedir => "ex/gpg");
       
    65 my $sign;
       
    66 eval {
       
    67     $sign =
       
    68       ($gpg->verify(signature => "$dir/message.sig", file => "$dir/message"));
       
    69 };
       
    70 if ($@) {
       
    71     $signed->add_header_line("\nX-GPGate-Sign: bad signature\n");
       
    72     print $signed->header_lines, "\n";
       
    73     print $signed->orig_body;
       
    74     exit 0;
       
    75 }
       
    76 
       
    77 $signed->add_header_line("\nX-GPGate-Sign: good signature\n");
       
    78 $signed->add_header_line("X-GPGate-SignUser: $sign->{user}\n");
       
    79 $signed->add_header_line("X-GPGate-KeyId: $sign->{keyid}\n");
       
    80 
       
    81 print $signed->header_lines, "\n";
       
    82 print $signed->orig_body;