OVH Cloud OVH Cloud

Problème C++

106 réponses
Avatar
Steph
boujour

J'ai créé un programme dont voici une partie :


#include <iostream>
using namespace std;

int main (void)

{
char pw[20];
const char valide[20]="12H12";

cout << " Password :";
cin >> pw;

while (strcmp(pw,valide) = =1)

{

cout << " ACCESS REFUSED\n ";
cout << " Password :";
cin >> pw;

}


cout << "\n ACCESS GARANTED ";
}

Le problème est que si j'entre seulement le premiere lettre ou chiffre il
accepte alors que celles qui suivent sont fausses. Comment je peux faire
pour que le programme teste un à un les caratères?

merci

10 réponses

Avatar
Michel Decima
In news:449bc4ca$0$1015$,
Sylvain typed:
kanze wrote on 23/06/2006 10:36:

Assez grosse, apparamment, que tu n'as pas réussi à le faire
correctement. Michel a déjà signalé le problème de EOF. Il y a


ce n'est un problème que pour ceux qui n'ont pas compris que je ne
fais aucun traitement chaine de caractères sur pw



J'ai parfaitement compris, et je te prie de relire les exemples que j'ai
fourni:

$ ./leSoftQuiVerifieLePassphrase < /dev/null
cnt
pw='ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'

ici, il n'y a aucun caracteres en entree, et pourtant le compteur est a 20,
alors qu'il devrait indiquer 0.

$ printf ABCD | ./leSoftQuiVerifieLePassphrase
cnt
pw='ABCDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'

Ici, il y a 4 caracteres en entree, sans 'n' ni 't', et pourtant le
compteur
indique toujours 20.

Que tu fasse par la suite des operations sur des chaines de caracteres (qui
supposent un '' ou non), ou du calcul differentiel ne change rien a
l'affaire,
le compteur ne reflete pas le nombre de caracteres fournis par
l'utilisateur,
donc le programme est casse des le depart.

Donc EOF reste un probleme a traiter.


Avatar
Michel Decima
In news:449bc1a4$0$871$,
Sylvain typed:
Michel Decima wrote on 23/06/2006 10:04:



#include <stdio.h>
int main() {
char pw[20]; // donné par le PO
int cnt = 0; // sorti nécessaire ensuite
for (; cnt < 20; ){
int c = getchar();
if (c == 'r' || c == 'n')
break;
pw[cnt++] = c;
}
printf("cnt=%dnpw='%s'n", cnt, pw);
}

$ ./leSoftQuiVerifieLePassphrase < /dev/null
cnt
pw='ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'

$ ./leSoftQuiVerifieLePassphrase < /dev/zero
cnt
pw=''

$ printf ABCD | ./leSoftQuiVerifieLePassphrase
cnt
pw='ABCDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'

L'incohérence entre la taille des donnees d'entree et la valeur de
cnt, ainsi que la presence des ÿ a l'affichage me suggere qu'il faut
encore faire quelque chose ici avant de passer aux problemes
d'attaque cryptographiques.


je dois re-re-répéter ?
je ne ferais jamais de strcmp (ni strlen, ni printf) donc le
passphrase saisi n'a *aucun* besoin d'être terminé par un


Ca je l'ai compris depuis le debut, merci.

j'ai juste besoin de sa longueur pour injecter les /cnt/ bytes(!) dans
un message digest.


Non, tu va injecter 20 bytes dans le digest, en completant le buffer
par un caractere special si l'utilisateur rentre moins de 20 caracteres.

Si tu ne traite pas EOF, le compteur cnt ne contient pas le nombre
de caracteres fournis par l'utilisateur.
Si tu ne complete pas le buffer, l'algorithme de comparaison ne
marche pas.

et btw, j'ai plus envie de faire un memset(pw, 0xFF, 20) qu'un
remplissage à zéro.


Et il faudra faire de meme pour le password stocke, sinon ca
ne marchera toujours pas.



Avatar
Gabriel Dos Reis
Sylvain writes:

[...]

| je dois re-re-répéter ?

parce que le fond n'est pas encore atteint ?

-- Gaby
Avatar
Gabriel Dos Reis
Sylvain writes:

| Gabriel Dos Reis wrote on 22/06/2006 17:56:
| > Et alors, le mot de passe de reference a aussi une longeur constante.
| > Explication à revoir.
|
| ça parait gros! tu as du sauter sauter un épisode ?!? ou confondre
| strcmp(s1, s2) avec memcmp(p1, p2, TheCommunFixedLength) ....

Non, merci.

| le PO indique:

ce sont tes follow-ups qui m'intéressent.

|
| reference = "12H12"
| candidats = "1" ou "12"
| instruction: strcmp(ref,candidate)
|
| insinues-tu que strcmp(s1, s2) effecture toujours sur une comparaison
| sur un nombre constant de caractères ?

Tu fustigeais l'utilisation de std::string. Retourne en arrière,
take a deeep breath and relax.

-- Gaby
Avatar
Gabriel Dos Reis
"Vincent Lascaux" writes:

| > les 2 opèrent donc en temps non constant; temps proportionnel à la plus
| > petite chaine pour strcmp; temps variable (nul ou prop. à la longueur)
| > pour string= |
| Il y a des chances pour que strcmp s'arrête "en gros" dès que les chaines
| different, non ?

en réalité, mon message concernait la réaction de Sylvain par rapport
à l'utilisation de std::string.

-- Gaby
Avatar
Gabriel Dos Reis
"kanze" writes:

[...]

| Il y a beaucoup de niveau de sécurité. C'est clair que si je me
| sers de strcmp directement sur le mot de passe, j'ai un niveau
| assez faible.

En effet. Je n'ai jamais pensé qu'il devrait faire un
strcmp. Cependant, Sylvain me semble fustiger une solution alors que
les remplacements qu'il proposent ainsi que les justifications me
paraissent pour le moins abracadabrantesques.

| Mais les variations dans le temps d'exécution de
| strcmp est loin d'être le maillon le plus faible. Si on accepte
| que le programme initial ne présente pas suffisamment de
| sécurité pour l'application en question, on commencerait sans
| doute par ne pas lire le mot de passe sur stdin/cin, mais plutôt
| sur une liaison sécurisée dont on peut vérifier la provenance,
| et qui assure que toute communication sur un reseau est
| encryptée. Et on ne comparerait pas les mots de passe eux-même,
| mais un hachage ou un encryptage à sens unique (MD5, SHA1, ou
| plus).
|
| Et, sans doute, on essaierait d'abord à faire un programme qui
| marche, sans erreurs. S'acharner sur les variations dans le
| temps d'exécution de strcmp, quand on a un débordement de
| buffer, me semble ne pas savoir gerer les priorités.

100% d'accord.

-- Gaby
Avatar
James Kanze
Sylvain wrote:

[...]
je mets plutot un flush avant chaque nouvel input.


Et depuis quand est-ce qu'un flux en entrée supporte un flush ?

Alors que :
std::string line ;
std::getline( std::cin, line ) ;
line.resize( 20, '' ) ;
résoud tous ces problèmes. En trois lignes, et d'une façon bien
plus lisible.



c'est bien !


Vanter une solution compliquée qui ne marche pas, par rapport à une
solution simple qui march, c'est bien une faute coupable, je crois.



c'est que tu n'as pas compris le but de la routine.


J'ai compris qu'elle ne marchait pas.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
Sylvain
Michel Decima wrote on 23/06/2006 13:56:

je ne ferais jamais de strcmp (ni strlen, ni printf) donc le

passphrase saisi n'a *aucun* besoin d'être terminé par un


Ca je l'ai compris depuis le debut, merci.


Michel Decima wrote on 23/06/2006 10:04:
In news:449b1880$0$886$,

On pourrait par exemple:
- forcer la terminaison de pw par un ''


problème de mémoire ou foutage de gueule ??

j'ai juste besoin de sa longueur pour injecter les /cnt/ bytes(!) dans
un message digest.


Non, tu va injecter 20 bytes dans le digest, en completant le buffer
par un caractere special si l'utilisateur rentre moins de 20 caracteres.


si j'ai envie seulement - j'ai indiqué cette alternative 2 posts plus
loin, soit ton newser a un pb, soit c'est à la lecture qu'il y a pb.

me dire "non, tu injecteras 20" quand je propose "d'injecter 20" dépasse
le dialogue de sourd !

Si tu ne traite pas EOF, le compteur cnt ne contient pas le nombre
de caracteres fournis par l'utilisateur.


ah c'est l'injection d'un buffer nul qui te gène !... je vois.

donc j'ai affaire à des gens qui confondent "temps passé à taper au
clavier" et temps du traitement de strcmp; il faut leur expliquer qu'un
pipe permet d'injecter des *annuaires* (plusieurs *mega*) de mots de
passe et tu viens noter que zéro car. ne marche pas !... tu as tout à
fait raison et on s'en fout complètement par rapport au pb exposé.

Si tu ne complete pas le buffer, l'algorithme de comparaison ne
marche pas.


ne veux rien dire.
je peux calculer un digest sur tout nombre de caractères (enfin de 0 à
2305843009213693952 pour les classiques).
je peux comparer bit à bit 20 octets qlq soit la façon dont ce hash est
calculé.

Et il faudra faire de meme pour le password stocke, sinon ca
ne marchera toujours pas.


"toujours pas" ?
sha1("123456") n'est pas égal à sha1"123456") ?
seul sha1("123456xxxxxxxxxxxxxx") est égal à sha1("123456xxxxxxxxxxxxxx") ?
je suis surpris !

surtout surpris que quitte à pinailler, il était possible d'indiquer que
le passphrase candidat comme celui de référence devaient être traité de
la même façon; cela me parait assez évident pour ne pas prendre son
temps à le dire ... mais je ne suis pas 'professionnel' moi et on est
plus à ça près.

Sylvain.



Avatar
Sylvain
Gabriel Dos Reis wrote on 23/06/2006 16:57:
| le PO indique:

ce sont tes follow-ups qui m'intéressent.


un follow-up ici ? c'est encore de l'ironie ?

il est impossible ici de discuter d'un problème algorithmique précis
sans que l'on déforme/extrapole/amplifie un détail hors sujet en
manquement grave à un 'idiome', une 'façon professionelle de'.

Tu fustigeais l'utilisation de std::string. Retourne en arrière,


tu peux me citer stp, on ne doit pas partager la même def. de "fustiguer"

take a deeep breath and relax.


les arguments opposés ne sont que source de relaxation.

Sylvain.

Avatar
Sylvain
Gabriel Dos Reis wrote on 23/06/2006 17:02:

| Il y a beaucoup de niveau de sécurité. C'est clair que si je me
| sers de strcmp directement sur le mot de passe, j'ai un niveau
| assez faible.


ITT au 24ième post, merci de me rassurer sur ce point!

En effet. Je n'ai jamais pensé qu'il devrait faire un strcmp.


mais je n'en parle pas préférant jouer aux devinettes ? c'est ça ?
je n'affectionne pas / ne comprends pas ce type de comm. !

Cependant, Sylvain me semble fustiger une solution alors que


tjrs pas compris où fustigation il y aurait ... à moins que
"std::machin" eut été une insulte.

les remplacements qu'il proposent ainsi que les justifications me


le remplacement "state &= (candidate[i] == reference[i]);" ?

paraissent pour le moins abracadabrantesques.


dans quel monde bien lisse, bien conforme et normé vivez-vous ??

| Mais les variations dans le temps d'exécution de
| strcmp est loin d'être le maillon le plus faible.


ok, donc n'en parlons pas, prenons tous les lecteurs pour des niais: ils
ne peuvent comprendre qu'un problème à la fois, obligeatoirement le plus
simple. leur problème n'est que de faire un cin à la console et jamais
d'implémenter quoi que ce soit de manière fine.

| Si on accepte
| que le programme initial ne présente pas suffisamment de


et ça te gène qu'on n'est pas envie de l'accepter comme ... une fatalité
ou une nécessité d'ailleurs ?
ça te gène que l'on donne des pistes pour pallier à ce manque de sécurité ?

| sécurité pour l'application en question, on commencerait sans
| doute par ne pas lire le mot de passe sur stdin/cin, mais plutôt
| sur une liaison sécurisée dont on peut vérifier la provenance,


MDR !! peux-tu nous rappeller le % de données circulant par une LS
protégée ??

peux-tu préciser en quoi la vérification de la provenance *dans le
contexte présent* à un sens ?

(pistes: soit j'ai identifié la machine connectante (SSL/SSH) et je ne
sais rien de qui (quel humain ou quel cracker) accède au service; soit
j'ai authentifié l'utilisateur en tant que personne et je me demande
bien pourquoi je lui demanderait un passphrase).

| et qui assure que toute communication sur un reseau est
| encryptée.


chiffré.

| Et on ne comparerait pas les mots de passe eux-même,
| mais un hachage ou un encryptage à sens unique (MD5, SHA1, ou
| plus).


MD5 est obsolète et non sur.

l'encryptage à sens unique n'existe simplement pas. (enfin "chiffrement
à sens unique" n'existe pas, parce que encryptage ne veut rien dire).

comparer un hash plutôt que les données est une précaution du monde unix
que tu généralises sans recul et préconises sans arguments; le poser
comme argument d'autorité n'a aucun sens.
(ta carte bleue ne vérifie pas le hash du PIN code)

| Et, sans doute, on essaierait d'abord à faire un programme qui
| marche, sans erreurs.


et pas plus surtout !! en 2006 le vrai défi reste et demeure "saisie à
la console", un vrai beau programme !!

| S'acharner sur les variations dans le temps d'exécution
| de strcmp, quand on a un débordement de buffer,


tu as raison sur l'inutilité de l'archarnement à vouloir expliquer un
point face à des interlocuteurs qui le dénigrent et y opposent des
détails d'un tout autre domaine; je n'oublierais pas ce point.

| me semble ne pas savoir gerer les priorités.


pourquoi mettre priorités au pluriel ? ah oui c'est idiomatique, car
pour le reste tu n'as que répéter qu'il ne fallait traiter *que* le
buffer overflow.

Sylvain.