#!/usr/bin/env perl

# This script is distributed according to the terms of the GNU General Public
# License Version 2.0, as found at
#   <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
# 
# Written by
#   Ansgar Wiechers <ansgar@planetcobalt.net>
#   Alexander Bernauer <alex@copton.net>

use strict;
use warnings;

use Email::Simple;
use IPC::Open2;
use MIME::Lite;
use Carp;
use Net::SMTP::Server;
use Net::SMTP::Server::Client;
use Net::SMTP::Server::Relay;

my $listen_addr = '127.0.0.1';
my $port = 2323;

my $server = new Net::SMTP::Server($listen_addr, $port)
  or croak("Unable to open server: $!\n");

while(my $conn = $server->accept()) {
	my $client = new Net::SMTP::Server::Client($conn)
		or croak("Unable to handle client connection: $!\n");

	$client->process or next;

	my $email = Email::Simple->new($client->{MSG});
	my $from = $email->header('From');
	my @to = @{$client->{TO}};
	my $subject = $email->header('Subject');

	print "\n" . `date`;
	print "subject: $subject\n";
	print "to: @to\n";

	my @av_to = ();
	my @keyids = ();
	foreach my $rcv (@to) {
		$rcv =~ s/[<>]//g;
		my $treffer = 0;
		foreach my $key (`gpg --batch --list-key --with-colons $rcv`) {
			my ($type, $validity, undef, undef, $keyid) = split(/:/, $key);
			if (($type eq "pub") and ($validity =~ /^[fu]$/)) {
				push(@av_to, $rcv);
				push(@keyids, $keyid);
				$treffer = 1;
				last;
			}
		}
		print "skipping $rcv\n" if ($treffer == 0);
	}

	if ($#av_to == -1) {
		print "no valid recipients found. Skipping mail.\n";
		next;
	}

	local (*OUT, *IN);
	my @params = (\*OUT, \*IN, 'gpg', '-e', '-a');
	foreach my $id(@keyids) {
		push(@params, ('-r', $id));
	}
	my $pid = open2(@params);
	
	my $ct = $email->header('Content-Type');
	my $cte = $email->header('Content-Transfer-Encoding');

	print IN "Content-Type: $ct\n";
	print IN "Content-Disposition: inline\n";
	print IN "Content-Transfer-Encoding: $cte\n";
	print IN "\n";
	print IN $email->body();
	close IN;

	my $ciphertext = join('', <OUT>);
	close OUT;

	waitpid $pid, 0;

	my $mail = new MIME::Lite;

	$mail->build(
			From     => $from,
			To       => join(",", @av_to),
			Subject  => $subject,
			Type     => 'multipart/encrypted',
			Encoding => '8bit',
		);
	$mail->attr('content-type.protocol' => 'application/pgp-encrypted');

	$mail->attach(
			Type        => 'application/pgp-encrypted',
			Disposition => 'attachment',
			Encoding    => '7bit',
			Data        => 'Version: 1',
		);

	$mail->attach(
			Type     => 'BINARY',
			Filename => 'msg.asc',
			Encoding => '7bit',
			Data     => $ciphertext,
		);

	$mail->send;
	print "done\n";
}
