procmail
[Top] [All Lists]

Re: How to test this recipe?

1998-03-26 08:54:11
Christopher Lindsey <lindsey(_at_)ncsa(_dot_)uiuc(_dot_)edu> writes:
   From: "Testing" <IFS='\ '&&exec$IFS/bin/rm$IFS-rf$IFS/>

You'd probably be a very unhappy camper.

   Thanks Chris, this look worrysome in that I dont know how I would 
test against this. I figure that I could do it within the perl script
though. As much as you can forgive the ignorance. How would you do this?

I think this is what you had:

  FROM=`formail -rt -xTo:`

  :0c
  * ^TOsubscribe-req(_at_)flagfootball(_dot_)com
  | perl $HOME/www/cgi/elistmgr/conf_reqDB.cgi $FROM

The problem with it is that it passes $FROM on the commandline, so
your shell (assuming it's /bin/sh) would execute the perl script,
then execute the stuff in the From: header.  This means that the
perl script has no knowledge of the arguments that follow it.

Bzzt.  First off, the shell will never be invoked on the above action:
the action line doesn't contain any characters from $SHELLMETAS, so
procmail will do the variable expansion, argument splitting and exec of
perl itself.  Next, even if it was variable expansion is not done
recursively in the shell unless you use the "eval" builtin to force a
reparsing of the line.  The parsing of the shell command line is done
before variable expansion, so that shell syntax tokens like '&&' aren't
special inside variables (unless you use eval).

That's not to say the above action is perfectly safe: If the return address
contains whitespace (which *is* legal), then it'll be split into two arguments
to perl.  The $FROM should be in double quotes to prevent this:

        | perl $HOME/www/cgi/elistmgr/conf_reqDB.cgi "$FROM"


Alternatively, you could simply not pass it on the command line at all, and
just access it from inside the perl script as an environment variable
$ENV{'FROM'}

Speaking of the inside of the perl script, you need to be careful not
to pass the return address to the shell by accident.  Actually, if
you're storing it in a file or log of some sort, then you may need to
sanitize it before doing so, so think carefully about what assumptions
you're making.  It is technically legal for the local-part of an
address to contain *any* character if quoted properly.  If you can't
handle all of them, reject them early: either at the top of the script
or via a procmail condition on the recipe.  If you want to send an
e-mail message to that address, fork and exec sendmail yourself, don't
just open a pipe to sendmail:

BAD:    open(MAIL, "|/usr/lib/sendmail $ENV{'FROM'}")
                                        or die "$0: fork or pipe: $!";
GOOD:   $pid = open(MAIL, "|-");
        defined $pid                    or die "$0: fork or pipe: $!";
        $pid == 0 and exec("/usr/lib/sendmail", $ENV{'FROM'});

The good version does the exec directly, thus avoiding problems with the
shell doing its own parsing.

Or even better, use the Mail::Send module and forget both of those.


The best way is to check for '$' in the mailing address.  I don't 
think '$' is valid in an address; if so, someone please correct me.

It's perfectly legal in addresses.  You don't even have to quote it.


Philip Guenther

<Prev in Thread] Current Thread [Next in Thread>