#!/bin/sh
#
# dspam-deliver
#
# Script de entrega de correo con dspam para instalarse
# en los archivos de entrega .qmail
#
# Copyright (c) 2009 - 2015  Felipe Eduardo Sanchez Diaz Duran
# Todos los derechos reservados
#
#

VERSION="0.6.4"
FECHA="20170912"

####### Configuracion #######

# Directorio temporal
TMPDIR=/var/tmp/dspam-deliver

# Ruta a dspam
DSPAM=/usr/bin/dspam

# Ruta a maildir
MAILDIRBIN=/usr/bin/maildir

# Ruta a vdeliver
VDELIVER=/usr/bin/vdeliver

# Ruta a reformail
REFORMAIL=/usr/bin/reformail

# Ruta a maildirmake
MAILDIRMAKE=/var/qmail/bin/maildirmake

# Ruta a attach-filter
ATTACHFILTER=/usr/bin/attach-filter

#############################


# Valores por default para las opciones
VIRTUALDELIVER=1
QUARANTINE=0

# Procesamos las opciones
# "-L" : entrega local con maildir
# "-Q" : entregamos los spam al directorio de spam del usuario
while getopts ":LQ" opt; do
  case $opt in
    L)
      VIRTUALDELIVER=0
      ;;
    Q)
      QUARANTINE=1
      ;;
    \?)
      echo "$(basename $0): Opcion invalida: -$OPTARG" >&2
      exit 111
      ;;
    :)
      echo "$(basename $0): Opcion -$OPTARG requiere un argumento" >&2
      exit 111
      ;;
  esac
done

# Verificamos que la entrega no este desactivada
if [ -r "$HOME/domain-disabled" ]; then
   echo "Deliveries to this mail domain are disabled."
   echo
   cat "$HOME/domain-disabled"
   exit 100
fi

# Archivos temporales
TMPFILE=`mktemp $TMPDIR/dspam-deliver.XXXXXX` || exit 111
TMPFILE2=`mktemp $TMPDIR/dspam-deliver.XXXXXX` || exit 111

# Exportamos todas las variables que qmail-local crea para nosotros
# porque vdeliver necesita varias de ellas

export SENDER  NEWSENDER RECIPIENT USER HOME HOST LOCAL EXT HOST2 HOST3 HOST4 EXT2 EXT3 EXT4 DEFAULT DTLINE RPLINE UFLINE


# Procesamos con dspam
if [ "$VIRTUALDELIVER" = "1" ]; then
   $DSPAM --client --user $(echo $EXT@$HOST | tr 'A-Z' 'a-z') --deliver=innocent,spam --stdout > $TMPFILE
   dspam_retval=$?
else
   $DSPAM --client --deliver=innocent,spam --stdout > $TMPFILE
   dspam_retval=$?
fi

# Verificamos que el archivo contenga una firma de DSPAM
dspam_result=$( $REFORMAIL -x "X-DSPAM-Result:" < $TMPFILE ) || exit 111

# Solo nos interesa el mas reciente
# FIXME: Tal vez desde que nos llega el mensaje eliminar todos los
# FIXME: encabezados X-DSPAM-xxxxx ??? Eso ayudaria tambien
# FIXME: para detectar el caso en el que dspam se muere
dspam_result=$(echo "$dspam_result" | tail -n1)


# Ahora lo filtramos con attach-filter, si esta disponible
if [ -x "$ATTACHFILTER" ]; then
   "$ATTACHFILTER" < $TMPFILE > $TMPFILE2
   RETVAL=$?
   if [ $RETVAL -gt 0 ]; then
      exit $RETVAL
   fi
   cat $TMPFILE2 > $TMPFILE
fi

# DSPAM reporto un error?
if [ $dspam_retval -ne 0 ]; then

   # Un error en el procesamiento de dspam causa que entreguemos
   # normalmente el correo. Salimos con 0 para indicarle a qmail-local
   # que continue con la siguiente linea de .qmail que suponemos que
   # es algo como "| /usr/local/bin/vdeliver" o tal vez "./Maildir/"
   #
   # Normalmente saldriamos con 99 para indicarle a qmail-local
   # que ignore el resto del archivo .qmail porque aqui en el script
   # ya habriamos entregado el mensaje procesado con dspam.

   rm -f "$TMPFILE"
   echo "Error en procesamiento de dspam, continuando con instrucciones por default"
   exit 0
fi

# No hay resultado de DSPAM? Asumimos que hubo un error al procesar el
# mensaje y volvemos a las instrucciones por default. Lee el comentario
# del caso arriba para los detalles.

if [ -z "$dspam_result" ]; then
   rm -f "$TMPFILE"
   echo "DSPAM no reporto un resultado, continuando con instrucciones por default"
   exit 0
fi


# Esto va a aparecer en el log de la entrega en /var/log/mail
echo "$dspam_result"


# Si la cuarentena esta activa y es spam entonces
# lo entregamos a un directorio de cuarentena

if [ $QUARANTINE -eq 1 ]; then

   if [ $VIRTUALDELIVER -eq 1 ]; then
      spam_dir="${HOME}/users/$(echo ${EXT}|tr '.' ':')/.Spam"
   else
      spam_dir="${HOME}/Maildir/.Spam"
   fi

   if [ "$dspam_result" = "Spam" ]; then

    # Verificamos que exista el directorio de usuario
    if [ -d "$(dirname $spam_dir)" ]; then
      # Verificamos que exista el directorio de spam
      if [ ! -d "$spam_dir" ]; then
         # Si no existe lo creamos y suscribimos al usuario
         # FIXME soporte para suscripciones de distintos servidores IMAP.
         # FIXME Esto ahorita solo funciona con bincimap.
         $MAILDIRMAKE "$spam_dir" || exit 111
         # Suscribimos tanto a bincimap como a dovecot. El uno ignorara al otro de cualquier forma.
         echo "INBOX/Spam" >> $(dirname "$spam_dir")/.bincimap-subscribed || exit 111
         echo "Spam" >> $(dirname "$spam_dir")/subscriptions || exit 111
         echo "Creado $spam_dir" | logger -t dspam-deliver -p mail.info
      fi

      # Entregamos el mensaje en el directorio de spam
      cat $TMPFILE | /usr/bin/dos2unix -U | $MAILDIRBIN "$spam_dir" || exit 111
      rm -f "$TMPFILE"
      exit 99

    fi
   fi
fi


# Si no es spam, entregamos el mensaje al buzon del usuario
RETVAL=0
if [ "$VIRTUALDELIVER" = "1" ]; then
   cat $TMPFILE | /usr/bin/dos2unix -U | /usr/bin/filepipe $VDELIVER -S
   RETVAL=$?
else
   cat $TMPFILE | /usr/bin/dos2unix -U | $MAILDIRBIN $HOME/Maildir/
   RETVAL=$?
fi

rm -f "$TMPFILE"
rm -f "$TMPFILE2"

if [ $RETVAL -gt 0 ]; then
   exit $RETVAL
else
   exit 99
fi

