Masquer mot de passe
Résolu/Fermé
aadilove
Messages postés
25
Date d'inscription
dimanche 30 décembre 2012
Statut
Membre
Dernière intervention
20 juin 2013
-
11 mars 2013 à 14:49
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 14 mars 2013 à 21:23
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 14 mars 2013 à 21:23
A voir également:
- Affichez brièvement les caractères composant le mot de passe à mesure que vous les saisissez.
- Voir mot de passe wifi android - Guide
- Mot de passe administrateur - Guide
- Identifiant et mot de passe - Guide
- Trousseau mot de passe iphone - Guide
- Exemple de mot de passe à 8 caractères - Guide
4 réponses
Utilisateur anonyme
11 mars 2013 à 17:00
11 mars 2013 à 17:00
yosh !
Je sais pas si quelque chose existe, mais tu peux faire :
a chaque caractère différent de ENTER : je le stock, je clearscreen et j'affiche une '*' en plus
SI le caractère est enter => je valide mes caractères stockés
Je sais pas si quelque chose existe, mais tu peux faire :
a chaque caractère différent de ENTER : je le stock, je clearscreen et j'affiche une '*' en plus
SI le caractère est enter => je valide mes caractères stockés
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
11 mars 2013 à 18:49
11 mars 2013 à 18:49
Salut aadilove,
Sous Linux/Unix, tu dois suspendre l'écho à l'écran des caractères tapés.
Tu peux faire comme indiqué ici :
https://stackoverflow.com/questions/1196418/getting-a-password-in-c-without-using-getpass-3
Si tu tiens absolument à afficher des étoiles (pourquoi ?), c'est plus compliqué, et tu devrais sans doutes utiliser ncurses.
Comme cela :
http://www.cplusplus.com/articles/E6vU7k9E/#CURSES-e2
ncurses est une librairie en C, le code présenté sur ce lien mélange du C avec un style de programmation C++, mais cela devrait te donner une idée et c'est assez simple à corriger. Sinon, tu devrais trouver d'autres exemples programmés de façon plus orthodoxes en C.
Dal
Sous Linux/Unix, tu dois suspendre l'écho à l'écran des caractères tapés.
Tu peux faire comme indiqué ici :
https://stackoverflow.com/questions/1196418/getting-a-password-in-c-without-using-getpass-3
Si tu tiens absolument à afficher des étoiles (pourquoi ?), c'est plus compliqué, et tu devrais sans doutes utiliser ncurses.
Comme cela :
http://www.cplusplus.com/articles/E6vU7k9E/#CURSES-e2
ncurses est une librairie en C, le code présenté sur ce lien mélange du C avec un style de programmation C++, mais cela devrait te donner une idée et c'est assez simple à corriger. Sinon, tu devrais trouver d'autres exemples programmés de façon plus orthodoxes en C.
Dal
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
11 mars 2013 à 20:56
11 mars 2013 à 20:56
Écrire une * n'est pas beaucoup plus compliqué que passer le terminal en raw.
Avec ton premier lien, tu passes le terminal en raw. Dès que tu lis le caractère entré par l'utilisateur, tu affiches une '*'. Rien de plus.
Avec ton premier lien, tu passes le terminal en raw. Dès que tu lis le caractère entré par l'utilisateur, tu affiches une '*'. Rien de plus.
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
Modifié par [Dal] le 12/03/2013 à 11:36
Modifié par [Dal] le 12/03/2013 à 11:36
Salut fiddy,
Lorsqu'on permet à l'utilisateur de saisir quelque chose, il est aussi sympa de lui permettre d'effacer sa saisie :-), et donc de gérer la touche backspace, afin qu'elle efface le caractère (l'étoile) précédemment saisie, jusqu'à éventuellement l'étoile représentant la première, et gérer les données de façon correspondante... et gérer aussi la touche entrée, bien sûr.
Donc, si on veut correctement gérer ce type d'interface utilisateur, il faut aller un peu plus loin.
fgets qui est utilisée dans le premier lien ne permet pas de faire cela, car elle ne gère qu'un flux et attend ENTER (ou EOF).
Je pense que getchar pourrait être utilisé, avec le line buffering désactivé (en jouant avec ICANON) en plus de echo, et envoyer \b comme montré dans le 2ème lien pour effacer l'étoile affichée.
Bref, on peut se passer de ncurses, mais ce n'est de toutes façons pas trivial (avec ncurses ou pas, d'ailleurs), de gérer des "étoiles", au lieu de simplement ne rien renvoyer.
Dal
Lorsqu'on permet à l'utilisateur de saisir quelque chose, il est aussi sympa de lui permettre d'effacer sa saisie :-), et donc de gérer la touche backspace, afin qu'elle efface le caractère (l'étoile) précédemment saisie, jusqu'à éventuellement l'étoile représentant la première, et gérer les données de façon correspondante... et gérer aussi la touche entrée, bien sûr.
Donc, si on veut correctement gérer ce type d'interface utilisateur, il faut aller un peu plus loin.
fgets qui est utilisée dans le premier lien ne permet pas de faire cela, car elle ne gère qu'un flux et attend ENTER (ou EOF).
Je pense que getchar pourrait être utilisé, avec le line buffering désactivé (en jouant avec ICANON) en plus de echo, et envoyer \b comme montré dans le 2ème lien pour effacer l'étoile affichée.
Bref, on peut se passer de ncurses, mais ce n'est de toutes façons pas trivial (avec ncurses ou pas, d'ailleurs), de gérer des "étoiles", au lieu de simplement ne rien renvoyer.
Dal
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
13 mars 2013 à 20:43
13 mars 2013 à 20:43
[Dal],
Tu oublies un détail.
Je suis d'accord pour gérer la touche backspace. Mais il faut le faire dans les deux cas (affichage des étoiles ou sans affichage). En effet, en mode raw, chaque backspace provoquera un caractère dans la chaîne de caractère.
Tu oublies un détail.
Je suis d'accord pour gérer la touche backspace. Mais il faut le faire dans les deux cas (affichage des étoiles ou sans affichage). En effet, en mode raw, chaque backspace provoquera un caractère dans la chaîne de caractère.
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
Modifié par [Dal] le 14/03/2013 à 10:26
Modifié par [Dal] le 14/03/2013 à 10:26
Non, si seul l'écho est supprimé, le terminal fonctionne sans echo, mais avec le line buffering, et donc la touche backspace est gérée (comme la touche entrée) sans que tu aies à la gérer toi même (comme proposé dans le code sur SO, là https://stackoverflow.com/questions/1196418/getting-a-password-in-c-without-using-getpass-3).
Ce n'est que si tu veux "voir des étoiles", que tu dois supprimer le line buffering, en désactivant en plus le mode canonique, comme proposé dans mon code adapté là : https://forums.commentcamarche.net/forum/affich-27337373-masquer-mot-de-passe#13.
Dal
Ce n'est que si tu veux "voir des étoiles", que tu dois supprimer le line buffering, en désactivant en plus le mode canonique, comme proposé dans mon code adapté là : https://forums.commentcamarche.net/forum/affich-27337373-masquer-mot-de-passe#13.
Dal
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
Modifié par [Dal] le 12/03/2013 à 12:11
Modifié par [Dal] le 12/03/2013 à 12:11
Salut aadilove, fiddy,
Voilà un exemple que j'ai pu tester sur une machine FreeBSD compilé avec gcc, à laquelle je me connecte avec un terminal émulé par Putty, adapté à la fois du premier lien posté dans mon message https://forums.commentcamarche.net/forum/affich-27337373-masquer-mot-de-passe#2 et du 2ème, mais sans utiliser ncurses.
Il devrait fonctionner sous Linux aussi. Voir cependant les remarques ci-après.
La désactivation du line buffering permet de disposer de la touche pressée avec getchar() sans qu'il soit nécessaire de presser la touche entrée.
Le code proposé ci-dessus interdit aussi la saisie au delà de la capacité maximale de la chaîne password, gère backspace pour l'effacement des étoiles et entrée...
Note que le terminal peut être paramétré pour renvoyer autre chose que 127 (Ctrl-?) lorsque backspace est pressé. Ainsi, mon Putty me permet de paramétrer le terminal émulé en renvoyant Ctrl-H à la place.
Dal
Voilà un exemple que j'ai pu tester sur une machine FreeBSD compilé avec gcc, à laquelle je me connecte avec un terminal émulé par Putty, adapté à la fois du premier lien posté dans mon message https://forums.commentcamarche.net/forum/affich-27337373-masquer-mot-de-passe#2 et du 2ème, mais sans utiliser ncurses.
Il devrait fonctionner sous Linux aussi. Voir cependant les remarques ci-après.
#include <stdio.h> #include <stdlib.h> #include <termios.h> #define ENTER_KEY 10 #define BACKSPACE_KEY 127 int main(void) { struct termios oflags, nflags; char password[11]; char ch = ' '; int n = 0; /* disabling line buffering by disabling * canonical mode, in addition to * disabling echo */ tcgetattr(fileno(stdin), &oflags); nflags = oflags; nflags.c_lflag &= (~ICANON & ~ECHO); nflags.c_lflag |= ECHONL; if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) { perror("tcsetattr"); return EXIT_FAILURE; } printf("password (max len %lu): ", sizeof(password) - 1); do { ch = getchar(); if ( (ch != BACKSPACE_KEY) && (ch != ENTER_KEY) && (n < sizeof(password) - 1) ) { printf("*"); password[n] = ch; password[n+1] = '\0'; n++; } else if ( (ch == BACKSPACE_KEY) && (n > 0) ) { printf("\b \b"); n--; password[n] = '\0'; } } while (ch != ENTER_KEY); printf("You typed: %s\n", password); /* restore terminal */ if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) { perror("tcsetattr"); return EXIT_FAILURE; } return 0; }
La désactivation du line buffering permet de disposer de la touche pressée avec getchar() sans qu'il soit nécessaire de presser la touche entrée.
Le code proposé ci-dessus interdit aussi la saisie au delà de la capacité maximale de la chaîne password, gère backspace pour l'effacement des étoiles et entrée...
Note que le terminal peut être paramétré pour renvoyer autre chose que 127 (Ctrl-?) lorsque backspace est pressé. Ainsi, mon Putty me permet de paramétrer le terminal émulé en renvoyant Ctrl-H à la place.
Dal
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
Modifié par [Dal] le 12/03/2013 à 12:21
Modifié par [Dal] le 12/03/2013 à 12:21
Mais donc, c'est plus simple de se contenter d'annuler l'écho sur le terminal, pour ne pas avoir à afficher les étoiles et gérer tout ce qui en découle, et se contenter de faire comme décrit dans le premier lien posté :
https://stackoverflow.com/questions/1196418/getting-a-password-in-c-without-using-getpass-3
C'est aussi plus sûr, a priori, car une personne voyant l'écran ne pourra pas compter les étoiles, et en déduire le nombre de caractères composant le mot de passe.
Dal
https://stackoverflow.com/questions/1196418/getting-a-password-in-c-without-using-getpass-3
C'est aussi plus sûr, a priori, car une personne voyant l'écran ne pourra pas compter les étoiles, et en déduire le nombre de caractères composant le mot de passe.
Dal
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
13 mars 2013 à 20:46
13 mars 2013 à 20:46
c'est plus simple de se contenter d'annuler l'écho sur le terminal, pour ne pas avoir à afficher les étoiles et gérer tout ce qui en découle
En mode raw, le backspace affiche un caractère. Donc cela provoquera l'affichage d'une étoile. Mais cela reste cohérent avec l'entrée du caractère dans la chaîne de caractère. Si tu gères le backspace, tu devras le faire pour les deux variantes. Mais j'admets que cela sera un peu plus simple dans la variante sans affichage.
Pour la sûreté, je suis d'accord. Il n'y a pas photo :-).
En mode raw, le backspace affiche un caractère. Donc cela provoquera l'affichage d'une étoile. Mais cela reste cohérent avec l'entrée du caractère dans la chaîne de caractère. Si tu gères le backspace, tu devras le faire pour les deux variantes. Mais j'admets que cela sera un peu plus simple dans la variante sans affichage.
Pour la sûreté, je suis d'accord. Il n'y a pas photo :-).
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
Modifié par [Dal] le 14/03/2013 à 11:19
Modifié par [Dal] le 14/03/2013 à 11:19
En passant à la struct termios les paramètres appropriés, tu peux contrôler finement le comportement de la console, et définir dans le champ c_lflag que ECHO est retiré, tout en maintenant ICANON.
https://pubs.opengroup.org/onlinepubs/7908799/xsh/tcsetattr.html
https://pubs.opengroup.org/onlinepubs/7908799/xsh/termios.h.html
Cet extrait de man 3 tcflow est plus clair sur la question :
Donc, en conservant le "mode canonique", backspace, enter, etc., se comportent normalement, quand bien même l'écho est supprimé, car le terminal continue de traiter des lignes.
Sur la sécurité, c'est plus que de passer par la commande système stty (qui a le même degré de complexité), mais peut faire l'objet de tours de passe passe, comme montré dans ma proof of concept là https://forums.commentcamarche.net/forum/affich-27337373-masquer-mot-de-passe#24
Dal
... qui trouve que la lecture de ce topic commence à devenir compliquée.
https://pubs.opengroup.org/onlinepubs/7908799/xsh/tcsetattr.html
https://pubs.opengroup.org/onlinepubs/7908799/xsh/termios.h.html
Cet extrait de man 3 tcflow est plus clair sur la question :
Canonical and noncanonical mode The setting of the ICANON canon flag in c_lflag determines whether the terminal is operating in canonical mode (ICANON set) or noncanonical mode (ICANON unset). By default, ICANON set. In canonical mode: * Input is made available line by line. An input line is available when one of the line delimiters is typed (NL, EOL, EOL2; or EOF at the start of line). Except in the case of EOF, the line delimiter is included in the buffer returned by read(2). * Line editing is enabled (ERASE, KILL; and if the IEXTEN flag is set: WERASE, REPRINT, LNEXT). A read(2) returns at most one line of input; if the read(2) requested fewer bytes than are available in the current line of input, then only as many bytes as requested are read, and the remaining characters will be available for a future read(2). In noncanonical mode input is available immediately (without the user having to type a line-delimiter character), and line editing is disa abled.
Donc, en conservant le "mode canonique", backspace, enter, etc., se comportent normalement, quand bien même l'écho est supprimé, car le terminal continue de traiter des lignes.
Sur la sécurité, c'est plus que de passer par la commande système stty (qui a le même degré de complexité), mais peut faire l'objet de tours de passe passe, comme montré dans ma proof of concept là https://forums.commentcamarche.net/forum/affich-27337373-masquer-mot-de-passe#24
Dal
... qui trouve que la lecture de ce topic commence à devenir compliquée.
aadilove
Messages postés
25
Date d'inscription
dimanche 30 décembre 2012
Statut
Membre
Dernière intervention
20 juin 2013
13 mars 2013 à 17:57
13 mars 2013 à 17:57
Merci tout le monde pour vos propositions..Enfin de compte j'ai procédé de la manière suivante (sans afficher des '*') :
printf(" Passe : ");
system("stty -echo"); // aprés cette ligne tout caractère tapé sera caché
fgets(passe, sizeof(passe), stdin);
system("stty echo"); // on revient en mode normal
printf(" Passe : ");
system("stty -echo"); // aprés cette ligne tout caractère tapé sera caché
fgets(passe, sizeof(passe), stdin);
system("stty echo"); // on revient en mode normal
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
13 mars 2013 à 20:49
13 mars 2013 à 20:49
Bonne idée pour ne pas afficher les étoiles.
En revanche, l'utilisation de system("stty -echo"); est à bannir car cela pose des problèmes de sécurité et ce n'est même pas posix.
Mais si ces limites ne te dérangent pas, tu as encore plus simple avec la fonction getpass() qui fera ce que tu veux directement ;-).
Et pour info, attention avec fgets(), le '\n' sera stocké dans ta chaîne passe s'il y a la place.
En revanche, l'utilisation de system("stty -echo"); est à bannir car cela pose des problèmes de sécurité et ce n'est même pas posix.
Mais si ces limites ne te dérangent pas, tu as encore plus simple avec la fonction getpass() qui fera ce que tu veux directement ;-).
Et pour info, attention avec fgets(), le '\n' sera stocké dans ta chaîne passe s'il y a la place.
[Dal]
Messages postés
6194
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
11 octobre 2024
1 092
Modifié par [Dal] le 14/03/2013 à 10:18
Modifié par [Dal] le 14/03/2013 à 10:18
Oui, comme dit fiddy faire appel à une commande externe n'est pas terrible.
Voilà ton code avec la correction sur la chaîne récupérée par fgets suggérée par fiddy :
Voilà une exécution "normale" de ce code :
Et voilà un exemple de ce qu'un utilisateur, même non privilégié, peut faire de ce code (ici, avec le shell sh - Bourne Shell, adapter pour un autre shell la façon dont les variables d'environnement sont manipulées) :
Il faudrait au minimum mettre le chemin complet de stty ("/bin/stty" dans mon cas) dans ta commande system. Ce n'est pas pratique, car, on pourrait imaginer qu'un système la place ailleurs. Ensuite, tu n'es pas à l'abri non plus que cette commande là soit remplacée par une autre qui fait des tours de passe-passe (cela sera plus difficile), ou des vulnérabilités éventuelles de cette commande.
Dal
Voilà ton code avec la correction sur la chaîne récupérée par fgets suggérée par fiddy :
$ cat aadilove.c #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char passe[11]; char *p; printf(" Passe : "); /* aprés cette ligne tout caractère tapé * devrait être caché, sauf si un utilisateur * a substitué la commande stty */ system("stty -echo"); fgets(passe, sizeof(passe), stdin); if ((p = strchr(passe, '\n')) != NULL) *p = '\0'; /* retour en mode normal */ system("stty echo"); printf("\nVous avez tapé %s, mais rien " "ne devais s'afficher à la saisie\n", passe); return 0; }
Voilà une exécution "normale" de ce code :
$ gcc -Wall aadilove.c -o aadilove $ ./aadilove Passe : Vous avez tapé toto, mais rien ne devais s'afficher à la saisie
Et voilà un exemple de ce qu'un utilisateur, même non privilégié, peut faire de ce code (ici, avec le shell sh - Bourne Shell, adapter pour un autre shell la façon dont les variables d'environnement sont manipulées) :
$ whereis stty stty: /bin/stty /usr/src/bin/stty $ echo $PATH /sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin:/home/ccm/bin $ pwd /usr/home/ccm/temp/testcommandsub $ PATH=/usr/home/ccm/temp/testcommandsub:$PATH $ export PATH $ echo "echo 'coucou'" > stty ; chmod +x stty $ ./aadilove coucou Passe : toto coucou Vous avez tapé toto, mais rien ne devais s'afficher à la saisie
Il faudrait au minimum mettre le chemin complet de stty ("/bin/stty" dans mon cas) dans ta commande system. Ce n'est pas pratique, car, on pourrait imaginer qu'un système la place ailleurs. Ensuite, tu n'es pas à l'abri non plus que cette commande là soit remplacée par une autre qui fait des tours de passe-passe (cela sera plus difficile), ou des vulnérabilités éventuelles de cette commande.
Dal
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
14 mars 2013 à 21:23
14 mars 2013 à 21:23
Exactement la faille de sécurité à laquelle je pensais.
Il faudrait au minimum mettre le chemin complet de stty
Cela ne change rien ^^. Juste une 6 caractères à taper en plus (sans compter la touche entrée ^^) pour contourner l'appel à /bin/stty. Et on peut recommencer à jouer avec le PATH. Quoi que il me semble que cette ruse soit corrigée sur les noyaux supérieurs à 2.4. Il vaut mieux utiliser la famille exec().
Ou encore mieux, ton programme plus haut :-)
Il faudrait au minimum mettre le chemin complet de stty
Cela ne change rien ^^. Juste une 6 caractères à taper en plus (sans compter la touche entrée ^^) pour contourner l'appel à /bin/stty. Et on peut recommencer à jouer avec le PATH. Quoi que il me semble que cette ruse soit corrigée sur les noyaux supérieurs à 2.4. Il vaut mieux utiliser la famille exec().
Ou encore mieux, ton programme plus haut :-)
11 mars 2013 à 20:46
De plus, un écran effacé peut se retrouver sur certains OS en remontant l'ascenseur.
12 mars 2013 à 08:41
12 mars 2013 à 08:42
12 mars 2013 à 11:07
Les fonctions de lecture standards (getchar (), ...) ne lisent pas le clavier mais son buffer. Or, pour qu'un caractère entre dans le buffer clavier, il faut appuyer sur la touche entrée.
Le seul moyen est de passer en mode raw () comme dit par Dal.
12 mars 2013 à 11:37
elle te retourne la valeur entière de la touche appuyée (après faut se reporter à l'ascii simplement)