Bug#387003: SetSender ignored if send() called with no parameters
Shane Allen
sallen at hrsmart.com
Mon Sep 11 15:58:57 UTC 2006
Package: libmime-lite-perl
Version: 3.01-4
This is basically a duplicate of CPAN #2759 [1]. I will be updating the CPAN report as well.
>From the documentation:
-- begin --
SetSender
Unless this is explicitly given as false, we attempt to automatically set the -f argument to the first address that can be extracted from
the "From:" field of the message (if there is one).
What is the -f, and why do we use it?
Suppose we did not use -f, and you gave an explicit "From:" field in your message: in this case, the sendmail "envelope" would indicate the real user your process was running under, as a way of preventing mail forgery. Using the -f switch causes the sender to be set in the envelope as well.
-- end --
A simple test case:
root at test:~# cat test.pl
#!/usr/bin/perl -w
use strict;
use MIME::Lite;
my $msg = MIME::Lite->new(
From =>'foo at hrsmart.com',
To =>'sallen at hrsmart.com',
Subject =>'Helloooooo, nurse!',
Data =>"How's it goin', eh?"
);
$msg->send();
root at test:~# perl test.pl
root at test:~# tail -3 /var/log/exim/mainlog
2006-09-11 10:30:04 1GMnjX-0007Br-00 <= root at hrsmart.com U=root P=local S=507
2006-09-11 10:30:04 1GMnjX-0007Br-00 => sallen at hrsmart.com R=lookuphost T=remote_smtp H=mail.hrsmart.com [xx.xx.xx.xx]
2006-09-11 10:30:04 1GMnjX-0007Br-00 Completed
Here's the resulting message source:
X-Real-To: sallen at hrsmart.com
Return-Path: <root at hrsmart.com>
Received: from test.hrsmart.com ([xx.xx.xx.xx] verified)
by franklin.hrsmart.com (SMTP)
with ESMTP id 2191773 for sallen at hrsmart.com; Mon, 11 Sep 2006 10:30:20 -0500
Received: from root by test.hrsmart.com with local (Exim 3.36 #1 (Debian))
id 1GMnjX-0007Br-00
for <sallen at hrsmart.com>; Mon, 11 Sep 2006 10:30:03 -0500
Content-Disposition: inline
Content-Length: 19
Content-Transfer-Encoding: binary
Content-Type: text/plain
MIME-Version: 1.0
X-Mailer: MIME::Lite 3.01 (F2.72; B3.04; Q3.03)
Date: Mon, 11 Sep 2006 15:30:02 UT
From: foo at hrsmart.com
To: sallen at hrsmart.com
Subject: Helloooooo, nurse!
Message-Id: <E1GMnjX-0007Br-00 at test.hrsmart.com>
How's it goin', eh?
An alternate test case:
root at test:~# cat test.pl
#!/usr/bin/perl -w
use strict;
use MIME::Lite;
my $msg = MIME::Lite->new(
From =>'foo at hrsmart.com',
To =>'sallen at hrsmart.com',
Subject =>'Helloooooo, nurse!',
Data =>"How's it goin', eh?"
);
$msg->send_by_sendmail();
root at test:~# perl test.pl
root at test:~# tail -3 /var/log/exim/mainlog
2006-09-11 10:36:50 1GMnq6-0007Cg-00 <= foo at hrsmart.com U=root P=local S=507
2006-09-11 10:36:50 1GMnq6-0007Cg-00 => sallen at hrsmart.com R=lookuphost T=remote_smtp H=mail.hrsmart.com [xx.xx.xx.xx]
2006-09-11 10:36:50 1GMnq6-0007Cg-00 Completed
Message source:
X-Real-To: sallen at hrsmart.com
Return-Path: <foo at hrsmart.com>
Received: from test.hrsmart.com ([xx.xx.xx.xx] verified)
by franklin.hrsmart.com (SMTP)
with ESMTP id 2191967 for sallen at hrsmart.com; Mon, 11 Sep 2006 10:37:06 -0500
Received: from root by test.hrsmart.com with local (Exim 3.36 #1 (Debian))
id 1GMnq6-0007Cg-00
for <sallen at hrsmart.com>; Mon, 11 Sep 2006 10:36:50 -0500
Content-Disposition: inline
Content-Length: 19
Content-Transfer-Encoding: binary
Content-Type: text/plain
MIME-Version: 1.0
X-Mailer: MIME::Lite 3.01 (F2.72; B3.04; Q3.03)
Date: Mon, 11 Sep 2006 15:36:50 UT
From: foo at hrsmart.com
To: sallen at hrsmart.com
Subject: Helloooooo, nurse!
Message-Id: <E1GMnq6-0007Cg-00 at test.hrsmart.com>
How's it goin', eh?
Things to note:
1. The log lines in test #2 shows the message from foo, not root.
2. The Return-Path header in #2 shows the message from foo, not root.
These are the effects of the SetSender flag. It is supposed to be active by default, per the documentation.
The problem is a result of an inconsistency in send_by_sendmail, which I am filing an additional bug report about. send_by_sendmail has two "modes" of operation. In the first, if arguments are passed in, no further processing is done. A pipe is opened to sendmail, and the message is sent using that pipe. The sendmail instance is executed using only the arguments passed in to send_by_sendmail; no further processing is done. This means the SetSender flag is ignored.
The *actual* problem causing this issue is because the send() function uses default arguments for send_by_sendmail, which triggers the inconsistent behaviour noted above. From the module source:
380 ### Our sending facilities:
381 my $Sender = "sendmail";
382 my %SenderArgs = (
383 "sendmail" => ["$SENDMAIL -t -oi -oem"],
384 "smtp" => [],
385 "sub" => [],
386 );
.... <snip> ....
2440 sub send {
2441 my $self = shift;
2442
2443 if (ref($self)) { ### instance method:
2444 my ($method, @args);
2445 if (@_) { ### args; use them just this once
2446 $method = 'send_by_' . shift;
2447 @args = @_;
2448 }
2449 else { ### no args; use defaults
2450 $method = "send_by_$Sender";
2451 @args = @{$SenderArgs{$Sender} || []};
2452 }
2453 $self->verify_data if $AUTO_VERIFY; ### prevents missing parts!
2454 return $self->$method(@args);
2455 }
.... <snip> ....
2536 sub send_by_sendmail {
2537 my $self = shift;
2538
2539 if (@_ == 1) { ### Use the given command...
2540 my $sendmailcmd = shift @_;
2541
2542 ### Do it:
2543 open SENDMAIL, "|$sendmailcmd" or Carp::croak "open |$sendmailcmd: $!\n";
2544 $self->print(\*SENDMAIL);
2545 close SENDMAIL;
2546 return (($? >> 8) ? undef : 1);
2547 }
2548 else { ### Build the command...
2549 my %p = @_;
2550 $p{Sendmail} ||= "/usr/lib/sendmail";
2551
2552 ### Start with the command and basic args:
2553 my @cmd = ($p{Sendmail}, @{$p{BaseArgs} || ['-t', '-oi', '-oem']});
2554
2555 ### See if we are forcibly setting the sender:
2556 $p{SetSender} = 1 if defined($p{FromSender});
2557
2558 ### Add the -f argument, unless we're explicitly told NOT to:
2559 unless (exists($p{SetSender}) and !$p{SetSender}) {
2560 my $from = $p{FromSender} || ($self->get('From'))[0];
Suggested fixes:
1. Move the default argument construction to a separate function:
sub build_sendmail_args
{
# do the work occurring in lines 2549 - 2965
}
2. Change Sender Args like so:
380 ### Our sending facilities:
381 my $Sender = "sendmail";
382 my %SenderArgs = (
383 "sendmail" => [ build_sendmail_args() ],
384 "smtp" => [],
385 "sub" => [],
386 );
3. Modify sub send_by_sendmail to use build_sendmail_args (to avoid code duplication)
4. Modify the documentation:
SetSender
Unless this is explicitly given as false **or unless you override the arguments being passed to sendmail**, we attempt to automatically set the -f argument to the first address that can be extracted from the "From:" field of the message (if there is one).
[1] <http://rt.cpan.org/Public/Bug/Display.html?id=2759>
More information about the pkg-perl-maintainers
mailing list