Re: [exim] Run a command whenever a specific authenticated u…

Top Page
Delete this message
Reply to this message
Author: Phil Pennock
Date:  
To: Nathan Huesken
CC: exim-users
Subject: Re: [exim] Run a command whenever a specific authenticated usersends a mail
On 2009-04-02 at 17:10 +0200, Nathan Huesken wrote:
> acl_check_data:
>   warn  condition = ${if eq{$authenticated_id}{nhuesen@???} {yes}{no}}
>           message = ${run{/bin/bash -c echo $h_To >> /tmp/local}{}}
>           log_message = I would like to add $h_To

>
> I get the correct log message in the mainlog, so the code is executed
> (and it also tells me the correct h_To I would expect).
>
> But it does not toch /tmp/local at all ... and I do not know why :(.


So if you run "exim -be" then you'll be in an iteractive expansion test
environment, which will let you just expand ${run...} strings to debug
it. With a sample message in foo.eml you can do "exim -bem foo.eml" and
you'll even have $h_to: available.

If you add -d+expand then you'll see the string expansions happening.

I suspect that part of your problem is that the $h_to: value will
include angle-brackets around the email address, which will act as I/O
redirectors to the shell.

The next problem is that whatever you do will have to deal with shell
metacharacters such as backticks in the email address.

So while this *appears* to work:
DANGEROUS DO NOT USE: ${run{/bin/sh -c "echo '$h_to:' >> /tmp/me/local"}}
it's actually a security hole when presented with:
To: "Foo '`shell-commands-here`' Bar" <user@???>

One option is to use a command which takes just one parameter, the text
to add, and adds that to a file itself. That lets you avoid shell
quoting by getting the text out of where it's parsed as part of a
command-line. Or you could even do this from the ${run...} line
directly; this example uses bash but zsh works as well, but /bin/sh on
FreeBSD dislikes it -- I think this is a shell bug there. Anyway:

${run{/usr/local/bin/bash -c 'echo "\$1" >> /tmp/me/local' -- '$h_to:'}}

Here, we let the shell echo "$1":
* "..." to ensure that $1 is not split by $IFS
* \$ to get the dollar past Exim's string expansion
So the shell gets a command, then end of options, and then $h_to: in one
parameter (argv[4]) put there by Exim; the shell sees that as $1 and
because it's only referred to as a variable, with no eval, it's never
subject to expansion (only splitting, if $1 were not double-quoted).

Another option is to get this data by processing the logs which Exim
creates already.

Regards,
-Phil