#!/bin/bash
# blot-out.sh : Efface "toutes" les traces d'un fichier.

#  Ce script écrase un fichier cible avec des octets pris au hasard, puis avec
#+ des zéros, avant de le supprimer définitivement.
#  Après cela, même l'examen des secteurs du disque par des méthodes
#+ conventionnelles ne permet pas de retrouver
#+ les données du fichier d'origine.

PASSES=7         # Nombre d'écriture sur le fichier.
                 #  L'augmenter ralentit l'exécution du script,
		 #+ spécialement sur les gros fichiers.
TAILLEBLOC=1     #  Les entrées/sorties avec /dev/urandom requièrent la taille
                 #+ d'un bloc, sinon vous obtiendrez des résultats bizarres.
E_MAUVAISARGS=70 # Divers codes d'erreur
E_NON_TROUVE=71
E_CHANGE_D_AVIS=72

if [ -z "$1" ]   # Aucun nom de fichier spécifié.
then
  echo "Usage: `basename $0` nomfichier"
  exit $E_MAUVAISARGS
fi

fichier=$1

if [ ! -e "$fichier" ]
then
  echo "Le fichier \"$fichier\" est introuvable."
  exit $E_NON_TROUVE
fi  

echo
echo -n "Êtes-vous absolument sûr de vouloir complètement écraser \"$fichier\" (o/n) ?"
read reponse
case "$reponse" in
[nN]) echo "Vous avez changé d'idée, hum ?"
      exit $E_CHANGE_D_AVIS
      ;;
*)    echo "Écrasement du fichier \"$fichier\".";;
esac


longueur_fichier=$(ls -l "$fichier" | awk '{print $5}')
      # Le 5e champ correspond à la taille du fichier.

nb_passe=1

chmod u+w "$fichier"   # Autorise l'écrasement ou la suppression du fichier.

echo

while [ "$nb_passe" -le "$PASSES" ]
do
  echo "Passe #$nb_passe"
  sync         # Vider les tampons.
  dd if=/dev/urandom of=$fichier bs=$TAILLEBLOC count=$longueur_fichier
               # Remplir avec des octets pris au hasard.
  sync         # Vider de nouveau les tampons.
  dd if=/dev/zero of=$fichier bs=$TAILLEBLOC count=$longueur_fichier
               # Remplir avec des zéros.
  sync         # Vider encore une fois les tampons.
  let "nb_passe += 1"
  echo
done  


rm -f $fichier # Finalement, supprime le fichier brouillé et déchiqueté.
sync           # Vide les tampons une dernière fois.

echo "Le fichier \"$fichier\" a été complètement écrasé et supprimé."; echo


#  C'est une méthode assez sécurisée, mais inefficace et lente pour massacrer
#+ un fichier. La commande "shred", faisant partie du paquetage GNU "fileutils",
#+ fait la même chose mais de façon plus efficace.

#  Le fichier ne peut pas être récupéré par les méthodes habituelles.
#  Néanmoins...
#+ cette simple méthode ne pourra certainement *pas* résister à des méthodes
#+ d'analyse plus sophistiquées.

#  Ce script pourrait ne pas fonctionner correctement avec un système de fichiers
#+ journalisé.
#  Exercice (difficile) : corrigez ce défaut.

#  Le paquetage de suppression de fichier "wipe" de Tom Vier fait un travail
#+ bien plus en profondeur pour massacrer un fichier que ce simple script.
#     http://www.ibiblio.org/pub/Linux/utils/file/wipe-2.0.0.tar.bz2

#  Pour une analyse en détail du thème de la suppression de fichier et de la
#+ sécurité, voir le papier de Peter Gutmann,
#+     "Secure Deletion of Data From Magnetic and Solid-State Memory".
#           http://www.cs.auckland.ac.nz/~pgut001/secure_del.html


exit 0
