$head now uses: Mail::Header -> MIME::Head
authorshort <>
Mon, 7 Oct 2002 22:34:13 +0000 (22:34 +0000)
committershort <>
Mon, 7 Oct 2002 22:34:13 +0000 (22:34 +0000)
+PGP aware
 - default e-mail <pgp-01234567@jankratochvil.net>
   - default key read from "$HOME/.gnupg/options"
Fixed recipients list uniquization

perlmail-sendmail

index 3cf3f3f..900dded 100755 (executable)
@@ -9,7 +9,7 @@ use warnings;
 
 require Getopt::Long;
 use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG WIFSTOPPED WSTOPSIG);
-require Mail::Header;
+require MIME::Head;    # inherits Mail::Header
 require Mail::Address;
 require File::Basename;
 require Mail::Alias;
@@ -20,12 +20,33 @@ my $HOME="/home/short";
 # Mail-Alias-1.12 will clutter $_ !
 my @addr_addon=(Mail::Alias->new("/etc/aliases")->exists("sentout") ? ("sentout") : ());
 my $opt_F;
+my $is_pgp;
 sub FromAddress
 {
 my($rcpt,$iserror)=@_;
 
+       my $phrase=(defined $opt_F ? $opt_F : "Jan Kratochvil");
+       {
+               last if !$is_pgp;
+               last if $iserror;
+               local *F;
+               local $_;
+               my $filename="$HOME/.gnupg/options";
+               open F,$filename or do { warn "Open \"$filename\": $!"; last; };
+               local $/="\n";
+               my @keys=map((/^\s*default-key\s+(\S+)\s*$/),<F>);
+               @keys==1 or do { warn "Found ".scalar(@keys)." 'default-key's in your \"$filename\", ignoring"; last; };
+               close F or warn "Close \"$filename\": $!";
+               my $default_key=$keys[0];
+               $default_key=~/^[[:xdigit:]]{8}$/ or do { warn "Invalid 'default-key', ignoring: $default_key"; last; };
+               return Mail::Address->new(
+                               $phrase,
+                               'pgp-'.uc($default_key).'@jankratochvil.net',
+                               );
+               }
+       # !$is_pgp or fallback
        return Mail::Address->new(
-                       (defined $opt_F ? $opt_F : "Jan Kratochvil"),
+                       $phrase,
                        (!$iserror ? 'rcpt' : 'rcpterr')
                                        .'-'
                                        .(defined($rcpt->user()) ? $rcpt->user() : "NOUSER")
@@ -177,7 +198,7 @@ if (0
 # RedHat sendmail-8.9.3-20/src/main.c/main()/\Qif (FullName != NULL)\E
 #   for $opt_F is implemented by Mail::Address in our &FromAddress
 
-my $head=Mail::Header->new(\*STDIN);
+my $head=MIME::Head->new(\*STDIN);
 # We may (=will) change the contents and send it multiple times
 if (defined(my $msgid=$head->get("Message-ID"))) {
        $head->delete("Message-ID");
@@ -230,11 +251,23 @@ my $from_headername;
        # now $from_headername contains the header name to be replaced w/substituted value
        }
 
+# to be utilized later by &FromAddress
+$is_pgp=(1
+               && do { local $_=$head->mime_attr("Content-Type");          $_ && ~m#^multipart/(?:signed|encrypted)$#; }
+               && do { local $_=$head->mime_attr("Content-Type.protocol"); $_ && ~m#^application/pgp\b#; }
+               );
+
 my $exitcode=0;
 # !defined($rcpt) if we have no recipients
 # make the list unique to prevent dupes being normally filtered by sendmail(8)
 # one '{' is block-wrapper, another '{' is hash-indirection!
-my @rcpts=keys(%{{ map(($_=>1),(@addr ? @addr : (undef()))) }});
+# hash keys are just strings, never refs!
+# unify the list as Mail::Address instances
+my @rcpts=(!@addr ? (undef()) : values(%{{ map({
+               my $obj=$_;
+               $obj=parseone $obj if !ref $obj;
+               (!defined $obj ? () : (lc($obj->address())=>$obj));
+               } @addr) }}));
 
 my $stdin_body=(@rcpts<=1 ? undef() : do {     # store input data only if it will be used multiple times
                local $/=undef();
@@ -246,10 +279,6 @@ for my $rcpt (@rcpts) {
 
        if (defined $rcpt) {    # !defined($rcpt) if we have no recipients
                local $_;
-               if (!ref $rcpt) {
-                       $rcpt=parseone $rcpt;
-                       next if !defined $rcpt;
-                       }
                $opt_f=FromAddress($rcpt,1)->address() if !defined $opt_f;
                $head->replace($from_headername,FromAddress($rcpt,0)->format()) if $from_headername;
                }
@@ -274,7 +303,7 @@ for my $rcpt (@rcpts) {
                sendmail_orig_exec() if !$pid; # child
                }
        $head->print(\*SENDMAIL);
-       print SENDMAIL "\n";    # Mail::Header->print() eats the empty line but it doesn't print it
+       print SENDMAIL "\n";    # MIME::Head->print() eats the empty line but it doesn't print it
        if (defined($stdin_body)) {
                print SENDMAIL $stdin_body;
                }