#! /usr/bin/perl

use 5.010;
use strict;
use warnings;
use File::Temp;
use GnuPG;
use autodie qw(:all);

use blib;
use Message::2822;

umask(077);
my $dir = File::Temp->newdir();

my $signed = Message::2822->new(file => shift // "ex/mails/signed");

# output the original message if not 'multipart/sign'
my ($content_type) = ($signed->header_lines(qr/^content-type/i) =~ /\s+(\S+)/i);
unless ($content_type =~ /multipart\/signed/i) {
    print $signed->header_lines, "\n";
    print $signed->orig_body;
    exit 0;
}

my ($boundary) =
  ($signed->header_lines(qr/^content-type/i) =~ /boundary=['"](.*?)['"]/);

open(my $body, "+>$dir/body");
print {$body} $signed->orig_body;
seek($body, 0, 0);

# cut the message
open(my $message, "+>$dir/message");
my $last_line = "";
while (<$body>) {
    last if ($last_line =~ /^\s+$/ and /^--\Q$boundary\E/);
    next if (/^--\Q$boundary\E/);
    s/\r?\n/\r\n/g;
    print {$message} $last_line;
    $last_line = $_;
}

# cut the signature
open(my $signature, "+>$dir/message.sig");
my $in_sign = 0;
while (<$body>) {
    if (/^-----BEGIN\s+PGP\s+SIGNATURE-----$/ or $in_sign) {
        if (/^-----END\s+PGP\s+SIGNATURE-----$/) {
            $in_sign = 0;
            print {$signature} $_;
        }
        else {
            $in_sign = 1;
            print {$signature} $_;
        }
    }
}

seek($message,   0, 0);
seek($signature, 0, 0);

# ask GPG to verify it…
my $gpg = new GnuPG(homedir => "ex/gpg");
my $sign;
eval {
    $sign =
      ($gpg->verify(signature => "$dir/message.sig", file => "$dir/message"));
};
if ($@) {
    $signed->add_header_line("\nX-GPGate-Sign: bad signature\n");
    print $signed->header_lines, "\n";
    print $signed->orig_body;
    exit 0;
}

$signed->add_header_line("\nX-GPGate-Sign: good signature\n");
$signed->add_header_line("X-GPGate-SignUser: $sign->{user}\n");
$signed->add_header_line("X-GPGate-KeyId: $sign->{keyid}\n");

print $signed->header_lines, "\n";
print $signed->orig_body;
