ReadPassword
L'extrait de code peut être consulté sans aucune authentification.
Rédigé par
Thomas "Oxymore" Kowalski
readpasswd.c 3,80 Kio
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
/*
@requires pwd, un tableau de char de 17 éléments (16 caractères max + caractère nul)
@assigns modifie pwd pour le remplir avec le mot de passe entré
@ensures récupère le mot de passe entré par l'utilisateur sur stdin
le mot de passe fait au plus 16 caractères
si une erreur apparaît, la fonction renvoie -1, sinon elle renvoie la taille du mot de passe
*/
int readpasswd(char pwd[17])
{
char* ttypath =
ttyname(0) ? ttyname (0) :
ttyname(1) ? ttyname (1) :
ttyname(2);
int j;
for (j = 0; j < 17; j++)
pwd[j] = '\0';
printf("Mot de passe : ");
/* On desactive la sortie */
system("stty raw -echo");
int i = 0;
char c[1];
FILE *f;
if(!(f = fopen(ttypath, "w+")))
{
printf("Impossible d'ouvrir le terminal en lecture et ecriture : %s\n", strerror(errno));
system("stty raw -echo");
return -1;
}
int tronque = 1;
/*
Ce serait plus naturel de faire "tant que vrai" et de faire break si i >= 15, mais on a dit qu'on voulait pas l'utiliser.
On va bien jusqu'à i = 16 et pas i = 15, parce que sinon on ne peut pas entrer un mot de passe de 16 caractères et le modifier (dès que le seizième caractère est entré, on sort de la boucle)
Donc on autorise jusqu'à i = 16, mais si on entre un caractère quand i = 16, on sort de la boucle
*/
while (i <= 16)
{
/* On vérifie qu'on peut lire un caractère sur le terminal. */
if(!fread(&c, sizeof(char), 1, f))
{
printf("Impossible de lire un caractere sur le terminal : %s\n", strerror(errno));
system("stty raw -echo");
return -1;
}
/* Si jamais on a fait nouvelle ligne ou retour chariot, on sort */
if (c[0] == '\r' || c[0] == '\n')
{
tronque = 0;
break;
}
/* Si on a fait backspace, on efface un caractere */
if (c[0] == 127)
{
/* On vérifie quand même qu'on a au moins déjà tapé un caractère, sinon on va avoir du mal à effacer quoi que ce soit. */
if (i > 0)
{
/*
On efface le dernier caractère de la chaine.
Comme i donne l'indice du prochain caractère, on doit bien assigner pwd[i - 1] et pas pwd[i] !
*/
pwd[i - 1] = '\0';
/* On fait revenir "le curseur dans la chaîne" au caractère d'avant */
i--;
/*
Ecrire \b \b permet de
- Placer le curseur à gauche
- Remplacer le dernier caractère (donc un X ici) par un espace
- Replacer le curseur à gauche de l'espace pour que le prochain X prenne la place de celui qu'on a effacé.
*/
if(!fprintf(f, "\b \b"))
{
printf("Impossible d'effacer le dernier caractère : %s\n", strerror(errno));
system("stty raw -echo");
return -1;
}
}
}
/* Sinon, on ajoute un caractere dans notre chaine mot de passe */
else
{
/* Si on le tableau est rempli, alors on sort. */
if (i == 16)
break;
/* On affiche un X quand l'utilisateur tape un caractere. */
if(!fprintf(f, "X"))
{
printf("Impossible d'écrire X sur le terminal : %s\n", strerror(errno));
system("stty raw -echo");
return -1;
}
pwd[i] = c[0];
i++;
}
}
/* On a fini de lire le mot de passe, on affiche un retour à la ligne dans le terminal. */
fprintf(f, "\r\n");
/* On reactive l'affichage des caracteres tapes */
system("stty -raw echo");
if (tronque)
return 17;
else
return i;
}
int main(void)
{
char pass[17];
int taille = readpasswd(pass);
if(taille == -1)
{
printf("Erreur lors de la lecture du mot de passe !\n");
return EXIT_FAILURE;
}
else
{
if (taille == 17)
{
printf("Attention : le mot de passe a été tronqué !\n");
taille = 16;
}
printf("Mot de passe lu (%d caracteres) :\n", taille);
printf("%s", pass);
printf("\n");
}
return 0;
}
Veuillez vous inscrire ou vous se connecter pour commenter