minsmtpd.sh (4396 octets)


#!/bin/sh

#
# minsmtpd - le serveur smtp minimum.
#
# Ce programme est lance par nc (Netcat) via le script minsmtpd.
#

cd `dirname $0`

. ./commun-smtpd

#
# Pour que la commande 'date' renvoie la date en anglais (sinon, mutt il
# reconnait pas le message comme un mel)
#

unset LANG

Mail=""
Rcpt=""
From=""
To=""

#
# Affiche le message de bienvenue
#

echo "220 $Fqdn SMTP minsmtpd 1.0 ready at `date`"

#
# Premiere partie : lire les donnees du mel a expedier. Les commandes
# reconnues sont :
#     - HELO : identification de l'expediteur (facultatif) ;
#     - MAIL : adresse de l'expediteur ;
#     - RCPT : adresse du destinataire ;
#     - DATA : les donnees du mel ;
#     - QUIT : clore la session.
#
## Verifier dans la RFC si mail from: mdecore et mail mdecore marchent.
#

while read ligne
do

#
# Enlever le caractere de controle '\r' : lors de la communication
# client-serveur, le caractere fin de ligne envoyé est '\r\n'. Les
# lignes lues contiennent donc un '\r' en trop a la fin de chaque ligne
#

    ligne=`echo $ligne | tr -d '\015'`
    set -- $ligne

#
# La commande (le premier argument) peut etre en majuscule ou minuscule,
# donc on compare la commande transformee en majuscule
#

    Cmd=`echo $1 | tr [a-z] [A-Z]`

    case "$Cmd" in
        HELO) echo "250 $Fqdn Hello $USER@$2, pleased to meet you"
              ;;
        MAIL) Mail="ok" # MAIL from: user1@domaine1
              From=$3
              echo "250 $3... Sender ok"
              ;;
        RCPT) Rcpt="ok" # RCPT to: user2@domaine2
              To=$3
              echo "250 $3... Recipient ok"
              ;;
        DATA) [ -z "$Mail" ] && echo "503 MAIL first" && continue
              [ -z "$Rcpt" ] && echo "503 RCPT first" && continue
              echo "354 Enter mail, end with \".\" on a line by itself"
              while read ligne && [ "`echo $ligne | tr -d '\015'`" != "." ]
              do
                  echo "$ligne" >> $Tmp
              done
              echo "250 $Fic Message accepted for delivery"
              ;;
        QUIT) echo "221 $Fqdn closing connection"
              break
              ;;
        *) echo "502 unimplemented"
           ;;
    esac
done

#
# Deuxieme partie : a partir de l'adresse "nettoyee", on delivre le courrier
# a l'utilisateur ou on le met dans la file de depart si il n'est pas
# destine a notre domaine (si notre serveur de mels sert de relai)
#

#
# Si l'adresse ne contient pas de signe '@', on la complete avec le
# nom du domaine local
#

! echo "$To" | grep "@" > /dev/null && To="$To@$Domaine" #`hostname --domain`

#
# L'adresse peut etre de la forme mdecore@chez.moi ou <mdecore@chez.moi>
# Il faut donc "nettoyer" tout ca.
#
# On recupere le nom de domaine du destinataire
#

AdresseTo=`echo $To | sed -e "s/.*<//g" -e "s/>.*//g" -e "s/.*@//"`

#
# On recupere le nom du destinateur (un utilisateur ayant un compte)
#

Id=`echo $To | sed -e "s/.*<//g" -e "s/>.*//g" -e "s/@.*//"`

#
# Nom de domaine du destinataire valide
#

#if [ "$AdresseTo" == "`hostname --domain`" -o \
if [ "$AdresseTo" = "$Domaine" -o \
     "$AdresseTo" = "$Fqdn" ]
then

#
# Nom d'utilisateur du destinataire valide
#

    if id $Id > /dev/null 2>&1 && [ -n "$Id" ]
    then

#
# Livraison du mel a l'utilisateur local
#

        echo "livraison locale : $Id@$AdresseTo" >> $FicLog
        echo "From $USER@$Fqdn `date`" >> $BAL/$Id
        cat $Tmp >> $BAL/$Id # procmail -Y -d $Id mais fo etre root
    else

#
# L'utilisateur n'existe pas pour ce domaine -> envoie d'un mel d'erreur
# a l'expediteur
#

        if ChercheLoop
        then
            [ -n "$Id" ] && echo "Utilisateur inconnu : $Id@$AdresseTo" >> $FicLog
            [ -z "$From" ] && echo "Expediteur non specifie" >> $FicLog && break
        #[ ! "$From" ] && echo "Expediteur non specifie" >> $FicLog && break
            (cat << EOF
From: $DemonMailer@$Domaine
To: $From
Date: `date`
Subject: Unvalid user
X-Loop: $DemonMailer@$Domaine

EOF
            sed -e "s/TO/$To/" -e "s/UTILISATEUR/$Id/" \
            < format/utilisateur-non-valide
            cat $Tmp | while read ligne
            do
                echo "> $ligne"
            done
            ) > $Queue/$Fic
        fi
    fi

#
# Mel destine a un domaine exterieur -> dans la queue
#

else
    echo "vers domaine exterieur : $Id@$AdresseTo" >> $FicLog
    cp $Tmp $Queue/$Fic
fi

rm -f $Tmp

exit 0