[Avcheck] Scan only mails for some domains?

Michael Tokarev mjt@tls.msk.ru
Tue, 06 Nov 2001 21:51:27 +0300


Karsten Dambekalns wrote:
[Do you subscribed to avcheck list?  (to stop sending
you duplicates)...]

> 
> On Mon, Nov 05, 2001 at 10:08:50PM +0300, Michael Tokarev wrote:
> Hi,
> 
> I have been hacking away on the example:
> 
> > Example using bash:
> >
> >  logger ... "infected by $MSG: from=<$FROM> to=$*"
> 
> I moved that below below the admin notification - this way the admin
> gets notified anyway...
> 
> >  nocheck_rcpts=()
> >  check_rcpts=()
> >  for i do
> >    case "$i" in
> >      rcpt1@to.check|rcpt2@to.check) check_rcpts=("${check_rcpts[@]}" "$i") ;;
> >      *) nocheck_rcpts=("${nocheck_rcpts[@]}" "$i") ;;
> >    esac
> >  done
> 
> Learnt a lot about bash (I have written some scripts, but never used
> arrays), heh! Thanks :-) I changed the case to use egrep, to have case
> insensitivity.

This is tricky to done correctly.  If you'll write e.g.
 echo "$i" | egrep ...
then it is possible to have bad effects.  Postfix *usually* not allows
you to have recipients that starts with `-' (allow_min_users=no), but if
you'll change this setting in the future...  This is why `case' is more
safe than echo|egrep.

> >  if [ $#nocheck_rcpts[*] != 0 ] then
> >    # send infected mail to all rcpts non-interested to have their mails checked
> >    $SENDMAIL -f "$FROM" -- "${nocheck_rcpts[@]}" < $MAIL
> >    if [ $? != 0 ] ; then
> >      echo "Unable to send mail"
> >      exit $EX_TEMPFAIL
> >    fi
> >  fi
> 
> This injects the mail again - is it checked again? Obviously not,
> since this is the same as for the mail being sent to the admin. But
> how does postfix know that it should not check this mail? More
> specifically, why is this mail sent to localhost:1025 (or whatever
> configured)? Or am I not seeing something terribly obvious here? Is
> this in $SENDMAIL? Puzzled...

;).  Look into avcheck manpage.  Avcheck will set $SENDMAIL to point
to whatether (re)injection path was configured in master.cf -- so yes,
this is $SENDMAIL.  In the example scripts, there is a line like
 : ${SENDMAIL:-/usr/sbin/sendmail -i}
to allow script execution manually, when it is not called from avcheck.
But when it is called by avcheck, $SENDMAIL is set up to whatether
is configured -- to use the same injection path that avcheck uses itself
to inject clean mail into postfix.  This is a trick I did in order to
allow `infected' script to work properly.

> >
> >  if [ $#check_rcpts[*] = 0 ] ; then
>          ^^^^^^^^^^^^^^^ should have curly braces around, no?

Yes, you're right.  This should be ${#check_rcpts[*]}.  I didn't checked
what I wrote -- just to show an idea... ;)

> >    # no other recipients
> >    exit 0
> >  fi
> >
> >  ... handle other recpients that wants their mail to be checked
> 
> OK, we didn't remove the stuff which should not be checked, did we? I
> mean, $* still has all the addresses, including the ones sorted out
> above. Or am I wrong here? Shouldn't there be a part removing the
> recipients that don't want their mail checked...

 ...
 set -- "${check_rcpt[@]}"

(Note here and in any other place.  Both quotes and usage of `@' instead
of `*' is essential -- this way you can safly deal with any (strange)
recipients you'll ever have.).

> (wait, I am thinking...)
> 
> OK, I see it now. There is no such part, but it isn't needed for the
> sender notification, right? If there are recipients left, for which
> mail should be checked, the sender notification will go out anyway.
> 
> But what about the recipients? Won't they get the mail _and_ the
> notification? They are still in $*...
> 
> Shed some light on this, please :-)

;)  The above line (set ...) will set $@/$* to rest of recipients for
you.  Or you can change $@/$* to ${check_rcpt[@/*]} in all other places...

Remember -- the example `infected' scripts are examples only (while
them are ready to run) -- I'm shure them are required to be changed
to suit any particular needs (or even rewritten from scratch).  Bash
allows *safe* operations with it's arrays and the like -- I'll be
glad to provide even more general scripts, but them will not run
by standard POSIX /bin/sh, and this particular task is difficult to
implement using standard /bin/sh either (/bin/ksh on e.g. Solaris
should do).

Regards,
 Michael.