#!/bin/bash

# Skrypt apm (Apache Password Manager, menedżer haseł Apache) umożliwia
# administratorowi łatwe tworzenie, zmienianie i usuwanie kont i haseł
# do podkatalogów w typowej konfiguracji serwera Apache (plik
# konfiguracyjny nosi nazwę .htaccess).

echo "Content-type: text/html"
echo ""
echo "<html><title>Menedżer haseł Apache</title><body>"

basedir=$(pwd)
myname="$(basename $0)"
footer="$basedir/apm-footer.html"
htaccess="$basedir/.htaccess"

htpasswd="`which htpasswd` -b"

# Ze względów bezpieczeństwa bardzo zalecane jest użycie poniższego kodu:
#
# if [ "$REMOTE_USER" != "admin" -a -s $htpasswd ] ; then
#   echo "Błąd: z APM może korzystać jedynie użytkownik <b>admin</b>."
#   exit 0
# fi

# Odczytanie z pliku .htaccess nazwy pliku z hasłami.

if [ ! -r "$htaccess" ] ; then
  echo "Błąd: nie można odczytać pliku $htaccess."
  exit 1
fi

passwdfile="$(grep "AuthUserFile" $htaccess | cut -d\   -f2)"
if [ ! -r $passwdfile ] ; then
  echo "Błąd: nie można odczytać pliku z hasłami. Wprowadzanie zmian niemożliwe."
  exit 1
elif [ ! -w $passwdfile ] ; then
  echo "Błąd: nie można zapisywać pliku z hasłami. Wprowadzanie zmian niemożliwe."
  exit 1
fi

echo -n "<center><h1 style='background:#ccf;border-radius:3px;"
echo "border:1px solid #99c;padding:3px;'>"
echo "Menedżer haseł Apache</h1>"

action="$(echo $QUERY_STRING | cut -c3)"
user="$(echo $QUERY_STRING|cut -d\& -f2|cut -d= -f2|tr '[:upper:]' '[:lower:]')"

case "$action" in
  A ) echo "<h3>Tworzenie nowego konta <u>$user</u></h3>"
        if [ ! -z "$(grep -E "^${user}:" $passwdfile)" ] ; then
          echo "Błąd: konto <b>$user</b> już istnieje."
        else
          pass="$(echo $QUERY_STRING|cut -d\& -f3|cut -d= -f2)"
          if [ ! -z "$(echo $pass|tr -d '[[:upper:][:lower:][:digit:]]')" ];
          then
            echo "Błąd: hasło może zawierać jedynie znaki a-z A-Z 0-9 ($pass)."
          else
            $htpasswd $passwdfile "$user" "$pass"
            echo "Konto utworzone!<br>"
          fi
        fi
        ;;
  U ) echo "<h3>Zmiana hasła do konta <u>$user</u></h3>"
        if [ -z "$(grep -E "^${user}:" $passwdfile)" ] ; then
          echo "Błąd: brak konta <b>$user</b> w pliku haseł."
          echo "Wyszukiwane konto &quot;^${user}:&quot; w pliku $passwdfile."
        else
          pass="$(echo $QUERY_STRING|cut -d\& -f3|cut -d= -f2)"
          if [ ! -z "$(echo $pass|tr -d '[[:upper:][:lower:][:digit:]]')" ];
          then
            echo "Błąd: hasło może zawierać jedynie znaki a-z A-Z 0-9 ($pass)."
          else
            grep -vE "^${user}:" $passwdfile | tee $passwdfile > /dev/null
            $htpasswd $passwdfile "$user" "$pass"
            echo "Hasło zmienione!<br>"
          fi
        fi
        ;;
  D ) echo "<h3>Usuwanie konta <u>$user</u></h3>"
        if [ -z "$(grep -E "^${user}:" $passwdfile)" ] ; then
          echo "Błąd: brak konta <b>$user</b> w pliku haseł."
        elif [ "$user" = "admin" ] ; then
          echo "Błąd: nie można usunąć konta 'admin'."
        else
          grep -vE "^${user}:" $passwdfile | tee $passwdfile >/dev/null
          echo "Konto usunięte!<br>"
        fi
        ;;
esac

# Zawsze należy tworzyć listę kont zapisanych w pliku haseł.

echo "<br><br><table border='1' cellspacing='0' width='80%' cellpadding='3'>"
echo "<tr bgcolor='#cccccc'><th colspan='3'>Lista "
echo "wszystkich kont</td></tr>"
oldIFS=$IFS ; IFS=":"   # Zmiana znaku rozdzielającego słowa...
while read acct pw ; do
  echo "<tr><th>$acct</th><td align=center><a href=\"$myname?a=D&u=$acct\">"
  echo "[usuń]</a></td></tr>"
done < $passwdfile
echo "</table>"
IFS=$oldIFS             # ... i przywrócenie go.

# Zapisanie wszystkich kont w zmiennej optionstring.
optionstring="$(cut -d: -f1 $passwdfile | sed 's/^/<option>/'|tr '\n' ' ')"

if [ ! -r $footer ] ; then
  echo "Uwaga: nie można odczytać pliku $footer."
else
  # Wyświetlenie stopki.
  sed -e "s/--myname--/$myname/g" -e "s/--options--/$optionstring/g" < $footer
fi

exit 0
