Contenu | Rechercher | Menus

Annonce

Si vous rencontrez des soucis à rester connecté sur le forum (ou si vous avez perdu votre mot de passe) déconnectez-vous et reconnectez-vous depuis cette page, en cochant la case "Me connecter automatiquement lors de mes prochaines visites".
Test de l'ISO d'Ubuntu francophone : nous avons besoin de testeurs pour la version francophone d'Ubuntu 14.04. Liens et informations ici.

Attention, une faille de sécurité dans bash a récemment été rapportée, il est recommandé de mettre à jour son système (plus de détails) *** mise à jour 12/10/2014 ***

#1 Le 28/02/2010, à 12:21

Totor

[JEU] challenge bash #5

1265482796.png

[informations sur le 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

Totor a écrit :

...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

Yannou90 a écrit :

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é wink


-- Lucid Lynx --

Hors ligne

#5 Le 01/03/2010, à 09:01

Yannou90

Re : [JEU] challenge bash #5

Merci tongue

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

survietamine a écrit :

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 roll
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 lol , 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 tongue) :

#!/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 yikes


-- 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 lol
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 lol ,parve que  la je suis a fond je ne peut pasfaire beaucoup mieux , peut etre plus propre tongue

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. cool


La réponse est 42

Hors ligne

#13 Le 06/03/2010, à 17:56

Totor

Re : [JEU] challenge bash #5

twocats a écrit :
if [[ $(date +%s) -ge $(cat "$FICHIER_MDP") ]]

Argghh ! C'est du yaourt ça !

if [[ $(date +%s) -ge "${FICHIER_MDP}" ]]

c'est plus mieux. cool

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 roll. 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 hmm
Par contre j'ai noté la syntaxe que je ne maitrise pas et ne manquerais pas de l'utiliser , merci cool
PS: dure le man bash quand même , obligé de pratiquer pour comprendre/apprendre roll

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 tongue

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 çà sad

Totor: ba comme d'hab le script de tueur , il va me falloir quelques jour pour tout assimiler roll

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

Yannou90 a écrit :

Ben non c'est pas juste je suis tout seul , c'est gagner par forfait çà sad

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 smile )

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 : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

Haut de page ↑