Pages : 1
#1 Le 28/02/2010, à 12:21
- Totor
[JEU] challenge bash #5
Gestionnaire de mot de passe
Un mot de passe est associé à un identifiant (utilisateur / login) et a une date début de validité. Il pourra également avoir une date de fin de validité. Ces dates sont "tronquées au jour" et doivent être cohérentes.
Le gestionnaire devra avoir les fonctionnalités suivantes :
- ajout d'un mot de passe (généré par un script du challenge #4)
- modification d'un mot de passe
- suppression d'un mot de passe
- modification des dates de validité (elles doivent être cohérentes)
Ces informations devront être persistantes et chiffrées.
bonne réflexion...
Dernière modification par Totor (Le 28/02/2010, à 12:23)
-- Lucid Lynx --
Hors ligne
#2 Le 28/02/2010, à 12:21
- Totor
Re : [JEU] challenge bash #5
Bon,
Voici ma solution.
Elle est bien plus complexe que ce qui était demandé. En effet, il s'agit d'une application qui tourne sous forme de "démon". Il faut donc le lancer dans un premier temps puis le "piloter" en ligne de commande. L'intérêt était pour moi et Nesthib de ne pas écrire le fichier à chaque fois qu'une demande de création/modification ou suppression était faite.
Les pré-requis :
- installer gpg
- créer une cléf avec une passephrase (attention, je n'ai pas testé avec plusieurs cléfs)
- la passephrase doit se trouver dans un fichier : ~/.gnupg/.passphrase (chmod 600 ~/.gnupg/.passphrase)
- netcat doit être installé (je le précise car je ne sais plus s'il l'est par défaut)
le script fonctionne avec mon générateur de mot de passe (mais tout autre solution peut-être utilisée en modifiant le gestionnaire). J'ai dû le modifier pour qu'il fonctionne sous forme de "fonction".
Voici le script genpwd.sh (qui doit se trouver dans le même dossier que le script du gestionnaire) :
#!/bin/bash
myHelp()
{
[ $# -ne 0 ] && echo >&2 -e "$@"
myName=${FUNCNAME[$((${#FUNCNAME[@]}-1))]}
cat >&2 <<EOF
Usage : ${myName} [[-c <key=value>] ...] [[-q <key=value>]...] [[-u <key=value>] ...] [-n <number>] [-d]
Options:
-c : Définition d'une classe (jeux de caractères)
-q : Indique la quantité de caractères de la classe devant être présents dans le mot de passe (nombre >=0)
-u : Indique si les caractères de la classe peuvent être en doublon dans le mot de passe (1 : unique; <>1 : doublon autorié)
-d : Utilise le device /dev/urandom plutôt que la variable bash RANDOM
-n : Nombre de mot de passe à générer (1 par défaut)
Valorisation:
key : identifiant numérique de la classe (>=0)
value : valeur de l'option pour la classe donnée
Classes:
Il existe 4 classes definies par défaut :
0 : ${charsMin}
1 : ${charsMaj}
2 : ${charsDig}
3 : ${charsSpe}
Si l'option -c est utilsée avec une "key" ayant une valeur déjà définie alors la classe correspondante est écrasée.
Si un caractère est commun à deux classes, la géneration du mot de passe n'a pas lieu.
Quantités et unicités :
La quantité par defaut est 2.
L'unicité par defaut est 1 (donc un caractère ne peut être en doublon).
EOF
[ $# -ne 0 ] && return 1
return 0
}
# suppression des espaces ajoutés par la commande {X..Y}
deleteSpaces()
{
chars="$@"
echo "${chars// }"
}
# Ajoute le caractère d'échappement avant tous les caractères de la chaine passée en paramètre
getPattern()
{
pattern=""
for((idx=0;idx<${#1};idx++))
do
pattern="${pattern}\\${1:${idx}:1}"
done
echo "${pattern}"
}
# verification du format key=valeur
verifOptionValue()
{
def="$1"
txt="$2"
[[ "${def}" != *=* ]] && { myHelp "Valeur non valide pour l'option ${option} : ${def}" ; return 1; }
id="${def%%=*}"
value="${def#*=}"
# test de la valeur de id
[[ "${id}" =~ [0-9]+ ]] || { myHelp "Identifiant non valide ${txt} : ${id}"; set +x; return 1; }
((id*=1))
nomTab="tab${id}"
# si la classe n'existait pas, on définit les valeur par défaut pour le nom du tablea, la quantité et l'unicité
[ ! "${tabTab[id]}" ] && {
tabTab[${id}]="${nomTab}"
eval "${nomTab}="
}
[ ! "${tabUnq[id]}" ] && tabUnq[${id}]=${defaultUnq}
[ ! "${tabQte[id]}" ] && tabUnq[${id}]=${defaultQte}
return 0
}
# definition d'une classe depuis une valeur passée à l'option -c en ligne de commande
setClass()
{
verifOptionValue "$1" "de classe" || return 1
# on definie le nom dans le tableau
tabTab[${id}]="${nomTab}"
# valorisation de la liste des caractère de la classe
eval "${nomTab}=\"${value}\""
}
# définitition d'une quantité de caractère à inclure dans le password depuis une valeur passée à option -q de la ligne de commande
setQte()
{
verifOptionValue "$1" "de quantité" || return 1
[[ "${value}" =~ [0-9]+ ]] || { myHelp "Quantité non valide pour l'id ${id} : ${value}"; return 1; }
((value*=1))
tabQte[${id}]="${value}"
}
# définitition d'une quantité de caractère à inclure dans le password depuis une valeur passée à option -q de la ligne de commande
setUnq()
{
verifOptionValue "$1" "d'unicité" || return 1
[[ "${value}" =~ [0-9]+ ]] || { myHelp "Unicitée non valide pour l'id ${id} : ${value}"; return 1; }
((value*=1))
tabUnq[${id}]="${value}"
}
# generation du password
genPwd()
{
pwd=""
allChars=""
tabChars=()
for((index=0;index<${#tabTab[@]};index++))
do
chars=""
[ ${tabQte[${index}]} -lt 0 ] && tabQte[${index}]=0
[ ${tabQte[${index}]} -ne 0 ] && {
nomTab="${tabTab[index]}"
chars="${!nomTab}"
tabChars[${index}]="${chars}"
allChars="${allChars}${chars}"
[ ${tabQte[index]} -gt ${#chars} ] && [ ${tabUnq[index]} -eq 1 ] && tabQte[index]=${#chars}
}
[ ! "${chars}" ] && tabQte[index]=0
tabRes[index]=tabQte[index]
done
length="${tabQte[@]}"
length="${length// /+}"
length=$((${length}))
while [ ${#pwd} -lt ${length} ];
do
${useRandom} && {
index=$((${#allChars}*${RANDOM}/32768))
char="${allChars:${index}:1}"
} || IFS="" read -n1 char < /dev/urandom
[ "${allChars}" ] && pattern="$(getPattern "${allChars}")" || char=""
char="${char/[^${pattern}]}"
[ "${char}" ] && {
# recherche du tableau auquel appartient le caractere
for ((index=0; index<${#tabTab[@]}; index++))
do
[ "${tabChars[index]}" ] && {
# il y a des caractères dans cette classe, on peut la vérifier
pattern="$(getPattern "${tabChars[index]}")"
[ "${char//[^${pattern}]}" ] && {
# on a trouve le tableau
# on peut rajouter le caractère au mot de passe car il reste au moins 1 caractère de cette classe à positionner dans le pwd
pwd="${pwd}${char}"
# on décrémente le nombre de caractères restant à ajouter pour cette classe
tabRes[index]=$((${tabRes[index]}-1))
[ ${tabUnq[index]} -eq 1 ] && {
# le caractère ne doit être présent qu'une seule fois, on le supprime donc des caractères autorisés
unChar="\\${char}"
tabChars[index]="${tabChars[index]//${unChar})}"
allChars="${allChars//${unChar}}"
}
[ ${tabRes[index]} -eq 0 ] && {
# on ne peut plus mettre de caractères de cette classe, on supprime donc tous les caractères de cette classe à ceux autorisés
pattern="$(getPattern "${tabChars[index]}")"
allChars="${allChars//[${pattern}]}"
tabChars[index]=""
}
}
}
done
}
done
echo "${pwd}"
}
# verification des caractères en commun entre 2 classes
verifClass()
{
for ((index=0;index<$((${#tabTab[@]}-1));index++))
do
nomTab="${tabTab[index]}"
chars="${!nomTab}"
for((idx=$((index+1)); idx<${#tabTab[@]};idx++))
do
nomTab="${tabTab[idx]}"
charsT="${!nomTab}"
pattern="$(getPattern "${charsT}")"
[[ "${chars}" == *[${pattern}]* ]] && { myHelp "Des caractères sont en communs entre deux classes : \n\tclasse n°${index}=${chars}\n\tclasse n°${idx}=${charsT}"; return 1; }
done
done
return 0
}
# tableau des caractères autorisés
charsMin="$(deleteSpaces {a..z})"
charsMaj="$(deleteSpaces {A..Z})"
charsDig="$(deleteSpaces {0..9})"
charsSpe="$ %~*'[]?@;.><()\"!"
defaultQte=2
defaultUnq=1
nbPwd=1
# tableau contenant la liste des tableaux
tabTab=( charsMin charsMaj charsDig charsSpe )
tabQte=( ${defaultQte} ${defaultQte} ${defaultQte} ${defaultQte} )
tabUnq=( ${defaultUnq} ${defaultUnq} ${defaultUnq} ${defaultUnq} )
newPwd()
{
OPTIND=0
userRandom=true
while getopts :c:q:u:n:dh option
do
case "${option}" in
c) setClass "${OPTARG}" || return ;;
q) setQte "${OPTARG}" || return ;;
u) setUnq "${OPTARG}" || return;;
d) useRandom=false;;
n) nbPwd="${OPTARG}"
{ [[ "${nbPwd}" =~ [0-9]+ ]] && ((nbPwd >= 1)) && ((nbPwd*= 1)) ; } || { myHelp "Nombre de mot de passe à générer non valide : ${OPTARG}"; return; } ;;
h) myHelp; return;;
:) myHelp "Argument manquant pour l'option '${OPTARG}'"; return;;
?) myHelp "Option non valide : ${OPTARG}."; return;;
esac
done
verifClass || return
for((cpt=1;cpt<=${nbPwd};cpt++))
do
genPwd
done
}
Le script du gestionnaire :
#!/bin/bash
# options :
# -s : start daemon (default)
# -q : quit daemon
# -f : flush data
#-h : print help
# option's parameters
# -p : port
#-S : Serveur
# actions
# -a : add
# -m : modify
# -r : remove
# -i : infos
# actions's parameters
# -d : start date
# -e : end date
defaultPort=2000
expand()
{
[ $# -lt 2 ] && { echo "Nombre de parametre invalide."; return 1; } >&2
nomVariable="$1"
variable="${!nomVariable}"
shift
for param
do
variable="$(eval "echo \"\${variable${param}}\"")"
[ $? -ne 0 ] && { echo "${!nomVariable}"; return; }
done
echo "${variable}"
}
gesHelp()
{
[ $# -ne 0 ] && echo -e "$@"
myName=${0##*/}
cat <<EOF
Usage : ${myName} [-sfqh] [-p <port> -s <serveur>] [ [-a|-m|-r|-i] <user> [-P] [-d <date>] [-e <date>]]
Options:
-s : Démarrer le démon (action par défaut)
-q : Quitter le démon
-f : Ecrire le fichier
-p : Port d'écoute (${defaultPort} par défaut)
-S : Serveur
-h : Affiche l'aide
-a : Ajouter un user
-m : Modifier un user
-r : Supprimer un user
-i : Affiche les informations d'un utilisateur
-P : Si présent, regénération du mot de passe
-d : Date de début de validité
-e : Date de fin de validité
EOF
[ $# -ne 0 ] && return 1
return 0
}
formatDate()
{
IFS="/" read -a tab <<< "$1"
echo "${tab[1]}/${tab[0]}/${tab[2]}"
}
getIndex()
{
user="$1"
# vérification de l'éventuelle existence du user
idx=-1
for((index=0; index<${#password[@]};index++))
do
pwd="${password[index]}"
[ "${pwd%%:*}" = "${user}" ] && idx=${index}
done
echo ${idx}
}
loadPassword()
{
mkdir -p "${PASSWORD_FILE%/*}"
[ ! -s "${PASSWORD_FILE}" ] && touch "${PASSWORD_FILE}";
chmod 600 "${PASSWORD_FILE}"
# ouverture du fichier PASSPHRASE_FILE en lecture et on associe le fd 3 à /dev/null en écriture
exec 5<"${PASSPHRASE_FILE}" 3>/dev/null
# on passe IFS="" pour ne pas perdre d'information (il est également possible de ne pas changer l'IFS mais il ne faut pas préciser de nom de variable)
password=()
while IFS="" read ligne
do
password+=( "${ligne}" )
done < <( gpg --batch --passphrase-fd 5 --logger-fd 3 -d "${PASSWORD_FILE}")
# fermeture des fichiers
exec 5<&- 3>&-
}
writePassword()
{
# ouverture du fichier PASSPHRASE_FILE en lecture et on associe le fd 3 à /dev/null en écriture
exec 5<"${PASSPHRASE_FILE}" 3>/dev/null
for unPwd in "${password[@]}"
do
[ "${unPwd}" ] && echo "${unPwd}"
done > >(gpg --yes --batch -o "${PASSWORD_FILE}" --passphrase-fd 5 --logger-fd 3 -c)
# protection du fichier
chmod 600 "${PASSWORD_FILE}"
# fermeture des fichiers
exec 5<&- 3>&-
}
addPassword()
{
user="$1"
startDate="$2"
endDate="$3"
# vérification de l'éventuelle existence du user
index=$(getIndex "${user}")
((${index} >= 0)) && return 1
startDate="$(formatDate "${startDate}")"
secStart="$(date +%s -d "${startDate}" 2>/dev/null)" || return 2
secEnd=""
[ "${endDate}" ] && {
endDate="$(formatDate "${endDate}")"
secEnd="$(date +%s -d "${endDate}" 2>/dev/null)" || return 2
((secEnd < secStart)) && return 2
}
unPwd="$(newPwd)"
password+=( "${user}:${secStart}:${secEnd}:${unPwd}" )
echo "${unPwd}"
}
modifyPassword()
{
user="$1"
startDate="$2"
endDate="$3"
mStartDate="$4" # doit on modifier la date de début
mEndDate="$5" # doit-on modifier la date de fin
mPassword="$6" # doit on regénérer le password
# vérification de l'éventuelle existence du user
idx=$(getIndex "${user}")
# le user n'a pas ete trouve, on retourne 1
[ ${idx} -eq -1 ] && return 1
IFS=":" read -a unPwd <<< "${password[idx]}"
secStart="${unPwd[1]}"
secEnd="${unPwd[2]}"
pwd="${password[idx]#*:*:*:}"
[ "${mStartDate}" ] && {
startDate="$(formatDate "${startDate}")"
secStart="$(date +%s -d "${startDate}" 2>/dev/null)" || return 2
}
[ "${mEndDate}" ] && {
secEnd=""
[ "${endDate}" ] && {
endDate="$(formatDate "${endDate}")"
endStart="$(date +%s -d "${endDate}" 2>/dev/null)" || return 2
}
}
[ "${mPassword}" ] && pwd="$(newPwd)"
password[idx]=( "${user}:${secStart}:${secEnd}:$(pwd)" )
[ "${mPassword}" ] && echo "${pwd}"
return 0;
}
removePassword()
{
user="$1"
idx=$(getIndex "${user}")
# le user n'a pas ete trouve, on retourne 1
[ ${idx} -eq -1 ] && return 1
password[idx]=""
}
printInfos()
{
user="$1"
idx=$(getIndex "${user}")
# le user n'a pas ete trouve, on retourne 1
[ ${idx} -eq -1 ] && return 1
IFS=":" read -a unPwd <<< "${password[idx]}"
dateDebut="$(date +"%d/%m/%Y" -d"@${unPwd[1]}")"
dateFin=""
[ "${unPwd[2]}" ] && dateFin="$(date +"%d/%m/%Y" -d"@${unPwd[2]}")"
echo "${dateDebut};${dateFin}"
}
startDaemon()
{
# le serveur est-il déjà démarré
[ -s "${PID_FILE}" ] && {
echo >&2 "Le fichier '${PID_FILE}' existe déjà."
return 1
}
mkdir -p "${PID_FILE%/*}"
echo $$ > "${PID_FILE}"
# chargement du fichier
loadPassword
while true
do
ligne="$(nc -l -p ${portNumber})"
[ $? -ne 0 ] && { echo >&2 "Erreur de connexion." ;break; }
add=""
modify=""
remove=""
user=""
dDebut=""
mDebut=""
dFin=""
mFin=""
mPassword=""
infos=""
set -- ${ligne}
OPTIND=1
while getopts :qfa:m:r:i:d:e:P option
do
case "${option}" in
q) writePassword
break 2;;
f) writePassword;;
i) infos="1"
user="${OPTARG}";;
a) add="1"
user="${OPTARG}";;
m) modify="1"
user="${OPTARG}";;
r) remove="1"
user="${OPTARG}";;
d) dDebut="${OPTARG}"
mDebut="1";;
e) dFin="${OPTARG}"
mFin="";;
P) mPassword="1";;
esac
done
# traitement des demandes
if [ $((add+modify+remove+infos)) -gt 1 ]; then
gesHelp "Une seule action sur l'utilisateur n'est possible en même temps."
else
[ "${add}" ] && addPassword "${user}" "${dDebut}" "${dFin}"
[ "${modify}" ] && modifyPassword "${user}" "${dDebut}" "${dFin}" "${mDebut}" "${mFin}" "${mPassword}"
[ "${remove}" ] && removePassword "${user}"
[ "${infos}" ] && printInfos "${user}"
fi
done
rm -f "${PID_FILE}"
echo "Démon arrété."
}
. ./genpwd.sh
# Fichier des mots de passe
SCRIPT="$0"
SHORT_NAME="$(expand SCRIPT "##*/" "%.*")"
PASSWORD_FILE="${HOME}/.${SHORT_NAME}/password"
PASSPHRASE_FILE=~/.gnupg/.passphrase
PID_FILE="${HOME}/.${SHORT_NAME}/${SHORT_NAME}.pid"
toStart=false
params=""
portNumber=""
serveur=""
[ $# -eq 0 ] && toStart=true
while getopts :sqfpS:a:m:r:i:d:e:Ph option
do
case "${option}" in
h) gesHelp
exit 0;;
:) gesHelp "Argument manquant pour l'option '${OPTARG}'"
exit 1;;
"?") gesHelp "Option non valide : ${OPTARG}."
exit 1;;
s) toStart=true;;
p) portNumber="${OPTARG}";;
S) serveur="${OPTARG}";;
*) params="${params} -${option} \"${OPTARG}\"";;
esac
done
portNumber=${portNumber:-${defaultPort}}
serveur="${serveur:-localhost}"
# on demande à démarrer le démon
${toStart} && {
startDaemon ${portNumber} &
disown -h %+
sleep 1
[ -s "${PID_FILE}" ] && echo "Le démon est démarré."
serveur="localhost"
}
# il y a des paramètres, on envoie au serveur
[ "${params}" ] && nc -c "echo ${params}" ${serveur} ${portNumber}
Le "man" :
Usage : gesPwd.sh [-sfqh] [-p <port> -s <serveur>] [ [-a|-m|-r|-i] <user> [-P] [-d <date>] [-e <date>]]
Options:
-s : Démarrer le démon (action par défaut)
-q : Quitter le démon
-f : Ecrire le fichier
-p : Port d'écoute (2000 par défaut)
-S : Serveur
-h : Affiche l'aide
-a : Ajouter un user
-m : Modifier un user
-r : Supprimer un user
-i : Affiche les informations d'un utilisateur
-P : Si présent, regénération du mot de passe
-d : Date de début de validité
-e : Date de fin de validité
EDIT : Le gestionnaire fonctionne uniquement "localement" mais avec quelques modifications, il est possible d'en faire un véritable client/serveur
EDIT2 : J'ai modifié le script pour pouvoir l'utiliser en vrai client/serveur
Dernière modification par Totor (Le 08/03/2010, à 22:55)
-- Lucid Lynx --
Hors ligne
#3 Le 28/02/2010, à 18:56
- Yannou90
Re : [JEU] challenge bash #5
...Ces dates sont "tronquées au jour" et doivent être cohérentes...
Bonjour a tous !
Petite question :que doit on comprendre par tronquées au jour et cohérentes ?
Que la durée de la validité expire apres 24 h , valide 1 jour quoi ?
Que cette date ne peut etre inferieur au moment de la creation du mdp et superieur a 24 heure pleines?
Hors ligne
#4 Le 28/02/2010, à 19:42
- Totor
Re : [JEU] challenge bash #5
Petite question :que doit on comprendre par tronquées au jour et cohérentes ?
Que la durée de la validité expire apres 24 h , valide 1 jour quoi ?
Que cette date ne peut etre inferieur au moment de la creation du mdp et superieur a 24 heure pleines?
tronqué au jour : les dates ne prennent pas en compte les unités en dessous du "jour". (i.e, pas d'heure, minute, ...)
cohérente : la date de fin de validité ne peut être antérieure à la date de début de validité
-- Lucid Lynx --
Hors ligne
#5 Le 01/03/2010, à 09:01
- Yannou90
Re : [JEU] challenge bash #5
Merci
Hors ligne
#6 Le 01/03/2010, à 20:38
- survietamine
Re : [JEU] challenge bash #5
salut,
donc par dates tronquées, tu souhaites à peu près ce que renvoie :
$(date +%Y%m%d)
ex : 20080528
?
Ðɸ Ƴơц ℕεєđ Şø₥€ √іêŤąɱίɳƸʂ ?
Hors ligne
#7 Le 02/03/2010, à 10:56
- Totor
Re : [JEU] challenge bash #5
salut,
donc par dates tronquées, tu souhaites à peu près ce que renvoie :$(date +%Y%m%d)
ex : 20080528
?
A toi de formater les dates comme tu le souhaites mais le but est simplement d'éviter de dire qu'un mot de passe a expiré à 15h32 et 15 secs... Il doit être valide à partir de la date de validité à 00h00:00 et ce jusqu'à la date de fin de validité à 00h00:00 (si elle est définie)
-- Lucid Lynx --
Hors ligne
#8 Le 02/03/2010, à 17:06
- Yannou90
Re : [JEU] challenge bash #5
Edit 3: Bon personne n'a encore poster donc j'ai réédité mon post pour ajouter quelques fonction , corriger le script , et essayer de le rendre plus lisible
Bonjour a tous
Bon j'ai pondu quelque chose qui correspond a peu près à l'énnoncer , c'est a dire :
-gestionnaire de mot de passe
-utilisation d'un script du précédent challenge (génération du mot de passe)
-création du mot de passe customisé
-modification du mot de passe
-modification de la date
-suppression du mot de passe si expiration de celui ci
-cryptage du fichier
Étant inccapable de créer un algorythme et encore moins de l'utiliser j ai utiliser ccrypt pour le chiffrement , rien que là je l'ai dans l'os
Le mot de passe n'apparait nulle part ,le nom d'utilisateur non plus (a moin de sniffer le pc pendant la creation ou le dechiffrement)
Utilisation :
/home/moguaye52/Bureau/script.sh -h
Utilisation : [script] [-u -n -d -r -C -l -Mmcsp]
Par défaut les options suivantes sont appliquées à l'utilisateur courant : [-n 10 -mMcs -d 0]
-l [CHAINE]
Afficher la date d'expiration du mot de passe de l'utilisateur CHAINE
-C [CHAINE]
Changer le mot de passe de l'utilisateut CHAINE
-r [CHAINE]
Supprimer le mot de passe de l'utilisateur CHAINE
-n [NOMBRE]
Nombre de caractères composants le mot de passe
-M
Majuscule
-m
Minuscule
-s
Caractères spéciaux
-c
Nombre
-p
Caractères définis par l'utilisateur composants le mot de passe : minuscules , majuscules , chiffres , caractères spéciaux
-u [CHAINE]
Utilisateur = CHAINE
-d [NOMBRE]
Durée de validitée du mot de passe exprimée en jours au delà de la journée courante
-h
Afficher les options disponibles
J'ai volontairement autorisé la création d'un mot de passe avec une date antérieur a celle du jour de la création , sinon pour tester il aurrait fallut attendre des plombes , pour ce faire il suffit de preciser un nombre de jour de validitée négatif (option -d -5 par exemple)
Bon le faut script vraiment pas clair (a mon image quoi ) :
#!/bin/bash
#Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon les termes
#de la Licence Publique Générale GNU publiée par la Free Software Foundation
#(version 2 ou bien toute autre version ultérieure choisie par vous).
#Ce programme est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE,
#ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation
# dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus
#de détails.
#Vous devez avoir reçu une copie de la Licence Publique Générale GNU en même temps
#que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, États-Unis.
## Déclaration des variables de base : ##
OPT_PASS="$1"
VAR_NBR="0"
NBR_FOI="1"
NBR_PASS="10"
MAJ_PASS=
MIN_PASS=
CHI_PASS=
SPE_PASS=
DEF_PASS="A-Za-z,-|0-9"
DATE_EXP="$(bc<<<$(date +%s)+86400)"
MDP_USER="$USER"
## Fonction d'affichage du manuel du script : ##
MAN_PASS()
{
printf "\nUtilisation : [script] [-u -n -d -r -C -l -Mmcsp]\n\nPar défaut les options suivantes sont appliquées à l'utilisateur courant : [-n 10 -mMcs -d 0]\n\n-l [CHAINE]\n Afficher la date d'expiration du mot de passe de l'utilisateur CHAINE\n-C [CHAINE]\n Changer le mot de passe de l'utilisateut CHAINE\n-r [CHAINE]\n Supprimer le mot de passe de l'utilisateur CHAINE\n-n [NOMBRE]\n Nombre de caractères composants le mot de passe\n-M\n Majuscule\n-m\n Minuscule\n-s\n Caractères spéciaux\n-c\n Nombre\n-p\n Caractères définis par l'utilisateur composants le mot de passe : minuscules , majuscules , chiffres , caractères spéciaux\n-u [CHAINE]\n Utilisateur = CHAINE\n-d [NOMBRE]\n Durée de validitée du mot de passe exprimée en jours au delà de la journée courante\n-h\n Afficher les options disponibles\n"
}
## Fonction de génération du mot de passe : ##
GENERE_MDP()
{
MDP_MDP=$(grep -a -o "["$DEF_PASS""$MAJ_PASS""$MIN_PASS""$CHI_PASS""$SPE_PASS"]" /dev/urandom | tr -d "\n" | head -c "$NBR_PASS")
}
## Fonction d'affichage des informations : ##
MDP_INFO()
{
echo -e "Utilisateur : ""$MDP_USER\n""Mot de passe proposé , généré aléatoirement : ""$MDP_MDP\n""Date d'expiration du mot de passe généré : ""$(date +%d/%m/%Y -d @$DATE_EXP)"
}
## Fonction pour vérifier l'expiration de la date de validitée : ##
TEST_DATE()
{
if [[ $(date +%s) -ge $(cat "$FICHIER_MDP") ]]
then
echo "Mot de passe expiré ! "
rm "$FICHIER_MDP"
exit 1
fi
EXP_MDP="$(date +%d/%m/%Y -d @"$(cat "$FICHIER_MDP")")"
echo "Date d'expiration enregistrée : ""$EXP_MDP"
}
## Fonction pour vérifier la validitée du mot de passe : ##
TEST_USER()
{
FICHIER_MDP=~/"$(md5sum<<<"$MDP_USER" | tr -d " -")"
if [ -e "$FICHIER_MDP" ]
then
cp "$FICHIER_MDP" "$FICHIER_MDP".bak
echo "Mot de passe de l'utilisateur ""$MDP_USER"
ccrypt -d "$FICHIER_MDP" >& /dev/null
if [ "$?" = "0" ]
then
TEST_DATE
else
echo "Mauvais mot de passe !"
mv "$FICHIER_MDP".bak "$FICHIER_MDP"
exit 1
fi
mv "$FICHIER_MDP".bak "$FICHIER_MDP"
else
echo "Aucun mot de passe pour l'utilisateur ""$MDP_USER"" !"
fi
}
while getopts ":C:n:u:d:r:l:Mmscp:" OPT_PASS
do
case "$OPT_PASS" in
l )
MDP_USER="$OPTARG"
TEST_USER
exit 0;;
C )
MDP_USER="$OPTARG"
FICHIER_MDP=~/"$(md5sum<<<"$MDP_USER" | tr -d " -")"
[ -e "$FICHIER_MDP" ] && ccrypt -x -f -P "Ancien mot de passe " -f -Q "Nouveau mot de passe " "$FICHIER_MDP" || echo "Aucun mot de passe pour l'utilisateur ""$MDP_USER"" !"
exit 0;;
u )
MDP_USER="$OPTARG";;
r )
MDP_USER="$OPTARG"
TEST_USER
rm "$FICHIER_MDP" >& /dev/null && echo "Suppression du mot de passe de ""$MDP_USER"
exit 0;;
n )
NBR_PASS="$OPTARG";;
M )
DEF_PASS=
MAJ_PASS='A-Z';;
m )
DEF_PASS=
MIN_PASS='a-z';;
s )
DEF_PASS=
SPE_PASS=',-|';;
c )
DEF_PASS=
CHI_PASS='0-9';;
p )
echo "Définissez les caractères"
read DEF_PASS;;
h )
MAN_PASS && exit 0;;
d )
DATE_EXP=$(bc<<<$(bc<<<"$OPTARG"*86400)+"$DATE_EXP");;
* )
MAN_PASS && exit 1;;
esac
done
TEST_USER
GENERE_MDP
MDP_INFO
echo "$DATE_EXP" | ccrypt -e -P "Mot de passe choisie par l'utilisateur" > "$FICHIER_MDP"
Exemple :
moguaye52@nunux:~$ /home/moguaye52/Bureau/script.sh
Aucun mot de passe pour l'utilisateur moguaye52 !
Utilisateur : moguaye52
Mot de passe proposé , généré aléatoirement : $$u,B2Vªk
Date d'expiration du mot de passe généré : 05/03/2010
Mot de passe choisie par l'utilisateur
Mot de passe choisie par l'utilisateur(repeat)
moguaye52@nunux:~$ /home/moguaye52/Bureau/script.sh -u ToTor
Aucun mot de passe pour l'utilisateur ToTor !
Utilisateur : ToTor
Mot de passe proposé , généré aléatoirement : iKj<Xy}r9=
Date d'expiration du mot de passe généré : 05/03/2010
Mot de passe choisie par l'utilisateur
Mot de passe choisie par l'utilisateur(repeat)
moguaye52@nunux:~$ /home/moguaye52/Bureau/script.sh -l ToTor
Mot de passe de l'utilisateur ToTor
Date d'expiration enregistrée : 05/03/2010
moguaye52@nunux:~$ /home/moguaye52/Bureau/script.sh -r ToTor
Mot de passe de l'utilisateur ToTor
Date d'expiration enregistrée : 05/03/2010
Suppression du mot de passe de ToTor
moguaye52@nunux:~$ /home/moguaye52/Bureau/script.sh -u sputnick -Mc -d 12
Aucun mot de passe pour l'utilisateur sputnick !
Utilisateur : sputnick
Mot de passe proposé , généré aléatoirement : 5F3TBF2JV6
Date d'expiration du mot de passe généré : 17/03/2010
Mot de passe choisie par l'utilisateur
Mot de passe choisie par l'utilisateur(repeat)
Dernière modification par Yannou90 (Le 04/03/2010, à 18:54)
Hors ligne
#9 Le 05/03/2010, à 23:00
- Totor
Re : [JEU] challenge bash #5
Bonsoir,
Et bien effectivement, ce challenge ne semble pas motiver la foule.
J'aimerai bien savoir pourquoi ...
Je vois que tu as pris de l'assurance.
Une première remarque :
Lorsque tu as plusieurs lignes à afficher, préfère l'utilisation de la notation "Here-Document" :
cat <<UN_MOT
ligne1
ligne2
ligne3
...
UN_MOT
Concernant le challenge, je dois dire que je suis étonné. Je m'attendais pas à avoir autant de fichier que d'utilisateur
-- Lucid Lynx --
Hors ligne
#10 Le 06/03/2010, à 10:26
- Yannou90
Re : [JEU] challenge bash #5
Bonjour
C'est ou nos "challengers" nous preparent un truc de fou , ou çà sent la grève
Complique tout de même de realiser un semblant de qqchose !
Lorsque tu as plusieurs lignes à afficher, préfère l'utilisation de la notation "Here-Document" :
cat <<UN_MOT
ligne1
ligne2
ligne3
...
UN_MOT
C'est vrai que je ne l'utilise que très rarement
Sinon l'utilisation de ccrypt est "autorisé" ? Je veux dire , c'est acceptable pour le challenge ou il faut se creer soit meme un algorythme et l'appliquer ,parve que la je suis a fond je ne peut pasfaire beaucoup mieux , peut etre plus propre
Hors ligne
#11 Le 06/03/2010, à 13:35
- Yannou90
Re : [JEU] challenge bash #5
Re-post : correction du script et possibilité de tester une valeur numérique négative pour la durée de validitée du mdp ; à commenter dans le script car sinon il faut attendre x jours , trop long ...
Le man :
Utilisation : [script] [-u -n -d -r -C -l -Mmcsp]
Par défaut les options suivantes sont appliquées à l'utilisateur courant : [-n 10 -mMcs -d 0]
-l [CHAINE]
Afficher la date d'expiration du mot de passe de l'utilisateur CHAINE
-C [CHAINE]
Changer le mot de passe de l'utilisateur CHAINE
-r [CHAINE]
Supprimer le mot de passe de l'utilisateur CHAINE
-n [NOMBRE]
Nombre de caractères composants le mot de passe
-M
Utilisation des majuscules pour la génération du mot de passe
-m
Utilisation des minuscules pour la génération du mot de passe
-s
Utilisation de caractères spéciaux pour la génération du mot de passe
-c
Utilisation de chiffres pour la génération du mot de passe
-p
Caractères définis par l'utilisateur pour la génération du mot de passe : minuscules , majuscules , chiffres , caractères spéciaux
-u [CHAINE]
Utilisateur = CHAINE
-d [NOMBRE]
Durée de validitée du mot de passe exprimée en jours au delà de la journée courante
-h
Afficher les options disponibles
Le script :
#!/bin/bash
#Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon les termes
#de la Licence Publique Générale GNU publiée par la Free Software Foundation
#(version 2 ou bien toute autre version ultérieure choisie par vous).
#Ce programme est distribué car potentiellement utile, mais SANS AUCUNE GARANTIE,
#ni explicite ni implicite, y compris les garanties de commercialisation ou d'adaptation
# dans un but spécifique. Reportez-vous à la Licence Publique Générale GNU pour plus
#de détails.
#Vous devez avoir reçu une copie de la Licence Publique Générale GNU en même temps
#que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, États-Unis.
## Déclaration des variables de base : ##
OPT_PASS="$1"
VAR_NBR="0"
NBR_PASS="10"
MAJ_PASS=
MIN_PASS=
CHI_PASS=
SPE_PASS=
DEF_PASS="A-Za-z,-|0-9"
DATE_EXP="$(bc<<<$(date +%s)+86400)"
MDP_USER="$USER"
## Fonction d'affichage du manuel du script : ##
MAN_PASS()
{
cat <<MANUEL
Utilisation : [script] [-u -n -d -r -C -l -Mmcsp]
Par défaut les options suivantes sont appliquées à l'utilisateur courant : [-n 10 -mMcs -d 0]
-l [CHAINE]
Afficher la date d'expiration du mot de passe de l'utilisateur CHAINE
-C [CHAINE]
Changer le mot de passe de l'utilisateur CHAINE
-r [CHAINE]
Supprimer le mot de passe de l'utilisateur CHAINE
-n [NOMBRE]
Nombre de caractères composants le mot de passe
-M
Utilisation des majuscules pour la génération du mot de passe
-m
Utilisation des minuscules pour la génération du mot de passe
-s
Utilisation de caractères spéciaux pour la génération du mot de passe
-c
Utilisation de chiffres pour la génération du mot de passe
-p
Caractères définis par l'utilisateur pour la génération du mot de passe : minuscules , majuscules , chiffres , caractères spéciaux
-u [CHAINE]
Utilisateur = CHAINE
-d [NOMBRE]
Durée de validitée du mot de passe exprimée en jours au delà de la journée courante
-h
Afficher les options disponibles
MANUEL
}
## Fonction de génération du mot de passe : ##
GENERE_MDP()
{
MDP_MDP=$(grep -a -o "["$DEF_PASS""$MAJ_PASS""$MIN_PASS""$CHI_PASS""$SPE_PASS"]" /dev/urandom | tr -d "\n" | head -c "$NBR_PASS")
}
## Fonction d'affichage des informations : ##
MDP_INFO()
{
echo -e "Utilisateur : ""$MDP_USER\n""Mot de passe proposé , généré aléatoirement : ""$MDP_MDP\n""Date d'expiration du mot de passe généré : ""$(date +%d/%m/%Y -d @$DATE_EXP)"
}
## Fonction pour vérifier l'expiration de la date de validitée : ##
TEST_DATE()
{
if [[ $(date +%s) -ge $(cat "$FICHIER_MDP") ]]
then
echo "Mot de passe expiré ! "
rm "$FICHIER_MDP"
exit 1
fi
EXP_MDP="$(date +%d/%m/%Y -d @"$(cat "$FICHIER_MDP")")"
echo "Date d'expiration enregistrée : ""$EXP_MDP"
}
## Fonction pour vérifier la validitée du mot de passe : ##
TEST_USER()
{
FICHIER_MDP=~/"$(md5sum<<<"$MDP_USER" | tr -d " -")"
if [ -e "$FICHIER_MDP" ]
then
cp "$FICHIER_MDP" "$FICHIER_MDP".bak
echo "Mot de passe de l'utilisateur ""$MDP_USER"
ccrypt -d "$FICHIER_MDP" >& /dev/null
if [ "$?" = "0" ]
then
TEST_DATE
else
echo "Mauvais mot de passe !"
mv "$FICHIER_MDP".bak "$FICHIER_MDP"
exit 1
fi
mv "$FICHIER_MDP".bak "$FICHIER_MDP"
else
echo "Aucun mot de passe pour l'utilisateur ""$MDP_USER"" !"
fi
}
## Fonction pour tester si la variable est une valeur numérique supérieur à 0 ##
TEST_NUM()
{
if [ -n "`echo "$1" | sed s/[0-9]*//`" ]
then
MAN_PASS
exit 1
fi
}
while getopts ":C:n:u:d:r:l:Mmscp:" OPT_PASS
do
case "$OPT_PASS" in
l )
MDP_USER="$OPTARG"
TEST_USER
exit 0;;
C )
MDP_USER="$OPTARG"
FICHIER_MDP=~/"$(md5sum<<<"$MDP_USER" | tr -d " -")"
[ -e "$FICHIER_MDP" ] && ccrypt -x -f -P "Ancien mot de passe " -f -Q "Nouveau mot de passe " "$FICHIER_MDP" || echo "Aucun mot de passe pour l'utilisateur ""$MDP_USER"" !"
exit 0;;
u )
MDP_USER="$OPTARG";;
r )
MDP_USER="$OPTARG"
TEST_USER
rm "$FICHIER_MDP" >& /dev/null && echo "Suppression du mot de passe de ""$MDP_USER"
exit 0;;
n )
TEST_NUM "$OPTARG"
NBR_PASS="$OPTARG";;
M )
DEF_PASS=
MAJ_PASS='A-Z';;
m )
DEF_PASS=
MIN_PASS='a-z';;
s )
DEF_PASS=
SPE_PASS=',-|';;
c )
DEF_PASS=
CHI_PASS='0-9';;
p )
echo "Définissez les caractères"
read DEF_PASS;;
h )
MAN_PASS && exit 0;;
d )
TEST_NUM "$OPTARG" ##Commenter cette ligne pour tester une date anterieur a celle de création sinon attendre $OPTARG jours pour vérifier (trop long)
DATE_EXP=$(bc<<<$(bc<<<"$OPTARG"*86400)+"$DATE_EXP");;
* )
MAN_PASS && exit 1;;
esac
done
TEST_USER
GENERE_MDP
MDP_INFO
echo "$DATE_EXP" | ccrypt -e -P "Mot de passe choisie par l'utilisateur" > "$FICHIER_MDP"
exit 0
Hors ligne
#12 Le 06/03/2010, à 15:11
- twocats
Re : [JEU] challenge bash #5
if [[ $(date +%s) -ge $(cat "$FICHIER_MDP") ]]
Argghh ! C'est du yaourt ça !
if [[ $(date +%s) -ge "${FICHIER_MDP}" ]]
c'est plus mieux.
La réponse est 42
Hors ligne
#13 Le 06/03/2010, à 17:56
- Totor
Re : [JEU] challenge bash #5
if [[ $(date +%s) -ge $(cat "$FICHIER_MDP") ]]
Argghh ! C'est du yaourt ça !
if [[ $(date +%s) -ge "${FICHIER_MDP}" ]]
c'est plus mieux.
pas vraiment : FICHIER_MDP est le nom d'un fichier et non une date
-- Lucid Lynx --
Hors ligne
#14 Le 06/03/2010, à 18:15
- twocats
Re : [JEU] challenge bash #5
'fectivement, 'avais pas bien lu . Mais j'aime pas les constructions avec cat, je préfère sourcer les fichiers.
La réponse est 42
Hors ligne
#15 Le 06/03/2010, à 19:13
- Yannou90
Re : [JEU] challenge bash #5
J'ai effectivement testé ton code dans mon script mais il comparait alors une valeur numerique a un fichier ce qui ne le fait pas
Par contre j'ai noté la syntaxe que je ne maitrise pas et ne manquerais pas de l'utiliser , merci
PS: dure le man bash quand même , obligé de pratiquer pour comprendre/apprendre
Hors ligne
#16 Le 07/03/2010, à 04:00
- Ph3nix_
Re : [JEU] challenge bash #5
PS: dure le man bash quand même , obligé de pratiquer pour comprendre/apprendre roll
Astuce du jour: konqueror man:bash (je suis sous ubuntu et ce navigateur ne sert que à ça)
Dernière modification par Ph3nix_ (Le 07/03/2010, à 04:01)
Hiroshima 45 / Chernobyl 86 / Windows '95
Hors ligne
#17 Le 07/03/2010, à 04:18
- Yannou90
Re : [JEU] challenge bash #5
J'en ai une autre : firefox man:bash mais çà ne rend pas l'apprentissage plus simple
Hors ligne
#18 Le 07/03/2010, à 22:06
- Totor
Re : [JEU] challenge bash #5
--- FIN DU CHALLENGE ---
le gagnant est Yannou90
une solution au post #2
n'oubliez pas de faire vos faire vos propositions de challenges
-- Lucid Lynx --
Hors ligne
#19 Le 08/03/2010, à 03:21
- Yannou90
Re : [JEU] challenge bash #5
Bonsoir ou bonjour a tous
Ben non c'est pas juste je suis tout seul , c'est gagner par forfait çà
Totor: ba comme d'hab le script de tueur , il va me falloir quelques jour pour tout assimiler
Et puis je suis deçu y a tellement de bon "scripteur" que c'est dommage de ce retrouver tous seul !!
Aller , c'est pas grave vivement le prochain !!
Dernière modification par Yannou90 (Le 08/03/2010, à 03:38)
Hors ligne
#20 Le 08/03/2010, à 04:08
- AnsuzPeorth
Re : [JEU] challenge bash #5
Ben non c'est pas juste je suis tout seul , c'est gagner par forfait çà
Tu es le seul qui a eu le courage de se lancer ... Personnellement, en ce moment, j'ai la tête dans le python, donc mon temps libre lui est consacré. Depuis le temps que je le dit ...( j'aurais du m'y mettre plus tot d'ailleurs ! je m'amuse comme un petit fou )
Félicitation pour l'heureux événement ! (+ 4 Kg, la pauvre ...:))
Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script (Hors ligne)
Hors ligne
#21 Le 08/03/2010, à 13:40
- Yannou90
Re : [JEU] challenge bash #5
Merci AnsuzPeorth
Hors ligne
#22 Le 10/03/2010, à 22:30
- nesthib
Re : [JEU] challenge bash #5
GUL Bordeaux : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde auto – ♥ awk
⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn
Hors ligne
Pages : 1