X-Git-Url: http://git.jankratochvil.net/?p=PerlMail.git;a=blobdiff_plain;f=perlmail-sendmail;h=c06a05124200b4bd0f84a175274205e3166d85e1;hp=3cf3f3fe3ae6f09a9c30590a53159d741961bd4f;hb=d9358d3afd47cd10415744c43fbd0bf58ca3947e;hpb=42c28285247c74238b364b82ef875fa83e0ab9a8 diff --git a/perlmail-sendmail b/perlmail-sendmail index 3cf3f3f..c06a051 100755 --- a/perlmail-sendmail +++ b/perlmail-sendmail @@ -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*$/),); + @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,12 +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); -# We may (=will) change the contents and send it multiple times -if (defined(my $msgid=$head->get("Message-ID"))) { - $head->delete("Message-ID"); - $head->replace("X-LaceMail-sendmail-Message-ID",$msgid); - } +my $head=MIME::Head->new(\*STDIN); # options leave in @ARGV, addresses to @addr: my @args=@ARGV; # temporary @ARGV=(); # options @@ -230,11 +246,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 +274,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 +298,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; }