информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Все любят медГде водятся OGRыСтрашный баг в Windows
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Google заблокировала 2 с лишним... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
fflush(stdin) и правда не помог... 09.04.03 16:22  Число просмотров: 2427
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
fflush(stdin) и правда не помог... Слушай, не подумай плохого, но что значит "прозрачный код" ? ;) Что-то типа легкий для понимания?
А что конкретно делает memset? У меня написано:
void *memset (void *s, int c, size_t n);
memset sets the first n bytes of the array s to the character c.

И пример:
#include <string.h>
#include <stdio.h>
#include <mem.h>

int main (void)
{
char buffer[] = "Hello world\n";
printf("Buffer before memset: %s\n", buffer);
memset(buffer, '*', strlen(buffer)-1);
printf("Buffer after memset: %s\n", buffer);
return 0;
}

По идее просто вся строка заменяется на звездочки...

А что в твоем случае делает memset ?
memset(pwd, sizeof(pwd), 0);

И еще... А куда тыкнуть free(pwd) ? И что возвращает return strdup(pwd); ?
Извини за то, что сильно гружу ;)
<programming>
Getpass меня не понимает ;) 05.04.03 17:18   [Ktirf]
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Всем привет! Вот такой вопрос:
Хочу использовать функцию getpass, вот пример:

#include <iostream.h>
#include <conio.h>

void main (void)
{
char *pass, str[20];
pass = getpass("Введите пароль: ");
cin.getline(str, sizeof(str));
cout << str;
}

Когда я откомпилил это дело в Borland Command Tools 5.5, то после ввода пароля, клавиша Enter как бы нажимается сама, и получается, что переменная str будет пустой и cout ничего не покажет...
Когда я компилил в Borland C++ 3.1, то все было нормально...
Дело в том, что мне нужно откомпилить именно в Borland Command Tools 5.5. Можно ли как то это исправить? Или может быть есть какая-то альтернатива функции getpass?
Всем большой сенькс ;)
Викинуть iostream... 08.04.03 16:31  
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Привет! Всем спасибо, что учавствовали в этой небольшой дискуссии. Я понял, что использовать одновременно stdio и iostream глупо... Потому что без iostream все работает пучком! Но твот только теперь придется научиться всем этим print'ам. Их так много! Голова распухла ;) Не знаете, где можно достать понятную инфу по ним с примерчиками (лучше на русском)?
Сенькс!
Напиши свою альтернативу - getch в цикле пока не вернет 13 05.04.03 18:07  
Автор: Killer{R} <Dmitry> Статус: Elderman
Отредактировано 05.04.03 18:13  Количество правок: 1
<"чистая" ссылка>
Кстати клавиша ентер возможно вводится из буфера (если ты ее например из ФАРа запускаешь)
А можно примерчик? 05.04.03 19:28  
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
> Кстати клавиша ентер возможно вводится из буфера (если ты
> ее например из ФАРа запускаешь)

Понимаешь, я новичок ;)) Напиши плиз какой-нибудь примерчик с использованием этого цикла strch(), а то у меня ничего не получилось...
Спасибо!!!!!
А можно примерчик? 05.04.03 20:22  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
printf("Введите пароль:");
char pas[32]={0};
char ch[2];ch[1]=0;
while(true)
{
ch[0]=getch();
if((ch[0]==13)|
strlen(pas)==31))break;
strcat(pas,ch);
}
Ну ни фига себе 07.04.03 18:17  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
<"чистая" ссылка>
> printf("Введите пароль:");
> char pas[32]={0};
> char ch[2];ch[1]=0;
> while(true)
> {
> ch[0]=getch();
>if((ch[0]==13)|strlen(pas)==31))break;
> strcat(pas,ch);
> }
Не могу назвать приведенный код оптимальным. Во-первых, использовать strcat для приписывания одного символа к концу массива - это медленно и некрасиво. Во-вторых, жестко ограничивается длина пароля. В-третьих (и между прочим, довольно важных), при нажимании 32-го символа клавиша Enter "нажмется" автоматически - не сказал бы, что этого ожидает пользователь.
Касаемо getpass. Первое. Не слишком это здорово - использовать одновременно cin/cout и функции из conio.h - они вообще говоря работают с разными сущностями (cin и stdin - не одно и то же). Второе. Если уж пользуешь их вместе, включи синхронизацию (sync_with_stdio функция называется, если не ошибаюсь). Но это все фигня. Главное - перед вводом пароля ОЧИЩАЙ БУФЕР! fflush (библиотека C) или cin.flush (библиотека C++) тебе поможет.
Если сам не сможешь написать или оно все-таки не будет работать - я могу привести пример того, как я бы это написал. Я бы предпочел использовать getpass - оно все-таки "правильнее" :)
Не получилось... 07.04.03 22:09  
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Включал sync_with_stdio. Пробовал очищать буфер fflush'ем... cin.flush я не нашел, зато нашел cout.flush ;) Но ничего не помогло. Напиши плиз пример!
И всем биг сенкькс :)
Тут не скорость кода важна думаю а его размер. А во вторых где ты видел пароли длинее 31 символов? 07.04.03 21:56  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
Насчет strcat и лишней строки. 08.04.03 14:54  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
Отредактировано 08.04.03 14:54  Количество правок: 1
<"чистая" ссылка>
Вместо использования char [2] и strcat достаточно вначале сделать memset на место хранения будущего пароля, а потом просто хранить номер текущей позиции символа. Имхо, в плане прозрачности код выигрывает, в плане занимаемого места, если не ошибаюсь, тоже. Хотя занимаемое место там в любом случае смешное. Спор скорее идеологический, признаю :)
Размер тоже не оптимален. Ответ на второй вопрос внутри 08.04.03 14:49  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
<"чистая" ссылка>
К сожалению, сейчас уже не припомню где (вполне возможно, что здесь: на БагТреке). Насчет того, а как же запоминать такие длинные пароли, ниже.
Вы случайно не сталкивались со следующей технологией использования пароля? После того как пароль был сгенерирован, некоторая его часть (скажем, 8 символов) запоминается, а остальное записывается в файлик, который сохраняется на дискете, защищаемой от записи.
И все-таки, как очистить буфер? 08.04.03 17:59  
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Я полностью перешел на stdio, не использовал iostream. Но все равно после ввода пароля или перед повторным его вводом "enter", будь он не ладен, "нажимается" сам!!! Напишите плиз кто-нибудь пример как очистить буфер перед вводом пароля... Весь хелп перелопатил, но ничего не понял :))
Сенькс!
Гм, я думал, ты наоборот на iostream перейдешь. Как раз в силу большей понятности. 08.04.03 19:35  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
<"чистая" ссылка>
Ссылок, к сожалению, кинуть не смогу, сам пользуюсь man'ами, поскольку сижу под линухом...
Касаемо примера - есть нехорошее ощущение, что гадит getpass. Или ты им уже не пользуешься? Кинь нынешний код, будем копать...
Вот код... 08.04.03 20:53  
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Выкидываем stdio, переходим на iostream ;)) А если серьезно, без функций из conio.h я вряд ли обойдусь, поэтому посижу пока в stdio. И опыту поднаберу... А к чему маны в линуксе? К компилятору? Может у меня тоже есть...
Вот весь код:

#include <string.h>
#include <conio.h>
#include <stdio.h>

char login[8];

void main (void)
{
char *pass;
int verif=1;

do
{

if (verif == 0)
{
cprintf("* Неверные логин или пароль!\r\n");
cprintf("----------------------------\r\n");
}

cprintf("* Логин: ");
gets(login);
pass = getpass("* Пароль: ");

char loginstr[18];
strcpy(loginstr, login);
strcat(loginstr, ":");
strcat(loginstr, pass);

/* ...
Здесь посторонний код
... */

if (strcmp(loginstr, "wade:qwer")==0)
verif=1; else verif=0;

// "wade:qwer" - это к примеру

}

while (verif==0);
}

Ну вот!! Попробуй введи неправильно... Курсор сразу перескочит на ввод пароля и вообще зависнет :((
[C++] Вроде все правильно. 08.04.03 22:33  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
Отредактировано 08.04.03 22:35  Количество правок: 1
<"чистая" ссылка>
> Выкидываем stdio, переходим на iostream ;)) А если
> серьезно, без функций из conio.h я вряд ли обойдусь,
> поэтому посижу пока в stdio. И опыту поднаберу... А к чему
> маны в линуксе? К компилятору? Может у меня тоже есть...
Если быть точным, к glibc, то есть к стандартной библиотеке C. По-моему, с Борландом тоже что-то такое идет.

> #include <string.h>
> #include <conio.h>
> #include <stdio.h>
>
> char login[8];
>
> void main (void)
> {
> char *pass;
> int verif=1;
>
> do
> {
>
> if (verif == 0)
> {
> cprintf("* Неверные логин или пароль!\r\n");
> cprintf("----------------------------\r\n");
> }
>
> cprintf("* Логин: ");
> gets(login);
-Здесь fflush(stdin); Я понимаю, что это скорее всего не поможет, но лучше пусть стоит. Не поможет от одного - поможет от другого.
> pass = getpass("* Пароль: ");
>
> char loginstr[18];
> strcpy(loginstr, login);
> strcat(loginstr, ":");
> strcat(loginstr, pass);
>
> /* ...
> Здесь посторонний код
> ... */
>
> if (strcmp(loginstr, "wade:qwer")==0)
> verif=1; else verif=0;
>
> // "wade:qwer" - это к примеру
>
> }
>
> while (verif==0);
> }
>
> Ну вот!! Попробуй введи неправильно... Курсор сразу
> перескочит на ввод пароля и вообще зависнет :((
Постой, а если правильно?

А вообще поразительно прозрачный код, непонятно почему не работает... Честно говоря, мне ничего не остается кроме как предложить написать свой getpass... :( Например, вот так (код не проверял!):
const char *getpass(const char *prompt) // Надеюсь, здесь не нужны строки printf-стиля?
{
    printf("%s", prompt); // Именно так, чтобы ненароком попавший в строку процент не завалил прогу.
    // Повторяю неудобство, которое было у Killer'а, потому что иначе слишком много писать.
    // В iostream с этим можно справиться, а в чистом C...
    char pwd[32];
    memset(pwd, sizeof(pwd), 0);
    int i = 0;
    for (char c = 0; (c = getch()) != 13); )
    {
        if (i < 32)
            pwd[i++] = c;
    }

    // Если нет strdup, то malloc(i); strcpy в выделенную область и возвращать уже ее.
    return strdup(pwd); 
}

---
Этот код (внимание!) требует освобождения выделенной памяти через free. Можно написать функцию так, чтобы пароль лежал в статической памяти, но тогда возникнет ряд трудностей.
Да, и скорее всего я что-нибудь забыл :)
fflush(stdin) и правда не помог... 09.04.03 16:22  
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
fflush(stdin) и правда не помог... Слушай, не подумай плохого, но что значит "прозрачный код" ? ;) Что-то типа легкий для понимания?
А что конкретно делает memset? У меня написано:
void *memset (void *s, int c, size_t n);
memset sets the first n bytes of the array s to the character c.

И пример:
#include <string.h>
#include <stdio.h>
#include <mem.h>

int main (void)
{
char buffer[] = "Hello world\n";
printf("Buffer before memset: %s\n", buffer);
memset(buffer, '*', strlen(buffer)-1);
printf("Buffer after memset: %s\n", buffer);
return 0;
}

По идее просто вся строка заменяется на звездочки...

А что в твоем случае делает memset ?
memset(pwd, sizeof(pwd), 0);

И еще... А куда тыкнуть free(pwd) ? И что возвращает return strdup(pwd); ?
Извини за то, что сильно гружу ;)
[C++] Стормозил я 09.04.03 20:15  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
<"чистая" ссылка>
> Слушай, не подумай
> плохого, но что значит "прозрачный код" ? ;) Что-то типа
> легкий для понимания?
Ага.

> А что в твоем случае делает memset ?
> memset(pwd, sizeof(pwd), 0);
Блин, так я и знал, что перепутаю... Наоборот параметры должны быть:
memset(pwd, 0, sizeof(pwd));
Так понятнее? :)

> И еще... А куда тыкнуть free(pwd) ? И что возвращает return
> strdup(pwd); ?
> Извини за то, что сильно гружу ;)
Да ладно :) free(pwd) нужно ставить туда, где этот пароль тебе уже больше не нужен будет. А функция strdup возвращает указатель на новую копию строки, которая была передана параметром. Память выделяется при помощи malloc-семейства, соответственно, каждому strdup, как и каждому malloc, должен соответствовать free.
free() что-то гонит :( 10.04.03 15:28  
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Я переписал getpas так, как предложил ты, но при возвращении в main, когда выполнение кода доходит до free(pwd), выскакивает ошибка :(, обратись говорит к разработчику и все будет гуд. Не знаешь почему появляется ошибка?

Вот получившийся код:

#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <alloc.h>

char *getpas(const char *prompt);

char logininput[8];
char pwd[32];

void main (void)
{
char *passinput;
int verif=1;

do
{

if (verif == 0)
{
cprintf("* Неверные логин или пароль!\r\n");
cprintf("----------------------------\r\n");
}

cprintf("* Логин: ");
gets(logininput);
fflush(stdin);
passinput = getpas("* Пароль: ");

char loginstr[18];
strcpy(loginstr, logininput);
strcat(loginstr, ":");
strcat(loginstr, passinput);

free(pwd);

if (strcmp(loginstr, "wade:qwer")==0)
{
verif=1;
break;
}
else verif=0;

}

while (verif==0);

}

char *getpas (const char *prompt)
{
printf("%s", prompt);
memset(pwd, 0, sizeof(pwd));
int i = 0;
char c;

while (i<32)
{
c = getche();
if (c !=13 ) pwd[i++] = c;
else break;
}

return strdup(pwd);
}

А почему вообще интересно происходит такое дело? Интересно, кто-нибудь когда-нибудь пользовался getpas'ом ? Наверное пользовались многие... ПОЧЕМУ ИМЕННО Я ВЛИП ?? :)
free() что-то гонит :( 10.04.03 17:15  
Автор: tatar_0x4e Статус: Member
<"чистая" ссылка>
> Я переписал getpas так, как предложил ты, но при
> возвращении в main, когда выполнение кода доходит до
> free(pwd), выскакивает ошибка :(, обратись говорит к
> разработчику и все будет гуд. Не знаешь почему появляется
> ошибка?
>
> Вот получившийся код:
>
> #include <string.h>
> #include <conio.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <alloc.h>
>
> char *getpas(const char *prompt);
>
> char logininput[8];
> char pwd[32];
>
> void main (void)
> {
> char *passinput;
> int verif=1;
>
> do
> {
>
> if (verif == 0)
> {
> cprintf("* Неверные логин или пароль!\r\n");
> cprintf("----------------------------\r\n");
> }
>
> cprintf("* Логин: ");
> gets(logininput);
> fflush(stdin);
> passinput = getpas("* Пароль: ");
>
> char loginstr[18];
> strcpy(loginstr, logininput);
> strcat(loginstr, ":");
> strcat(loginstr, passinput);
>
> free(pwd);
>
> if (strcmp(loginstr, "wade:qwer")==0)
> {
> verif=1;
> break;
> }
> else verif=0;
>
> }
>
> while (verif==0);
>
> }
>
> char *getpas (const char *prompt)
> {
> printf("%s", prompt);
> memset(pwd, 0, sizeof(pwd));
> int i = 0;
> char c;
>
> while (i<32)
> {
> c = getche();
> if (c !=13 ) pwd[i++] = c;
> else break;
> }
>
> return strdup(pwd);
> }
>
> А почему вообще интересно происходит такое дело? Интересно,
> кто-нибудь когда-нибудь пользовался getpas'ом ? Наверное
> пользовались многие... ПОЧЕМУ ИМЕННО Я ВЛИП ?? :)

Ты, наверное, хотел сказать не free(pwd), а free(passinput).

free(pwd) - ошибка.
Вот это утка :)) 10.04.03 18:46  
Автор: wade Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Короче, парни, такая штука:
Я все время компилил в C++ Builder Command Line Tools 5.5...
И все это время он <вырезано> портил прогу. Только что откомпилил в Borland C++ 3.1 (тот который под DOS) и все работает без проблем!
Только есть другая проблема. Borland C++ 3.1 не понимает функции типа getline из iostream и fstream =( Так что придется обходиться DOS'овскими... Там же есть что-то такое? ;)
Но все равно всем спасибо!!! Особенно тебе, Ktirf :))
Однако это не в первый раз на моей памяти 10.04.03 19:02  
Автор: Ktirf <Æ Rusakov> Статус: Elderman
Отредактировано 10.04.03 19:03  Количество правок: 1
<"чистая" ссылка>
Я вообще старался хорошо относиться к C++ Builder Command Line Tools, но по-моему, здесь уже пролетали жалобы на проблемы с версией 5.5, которые излечивались компиляцией на 3.1...

> Только есть другая проблема. Borland C++ 3.1 не понимает
> функции типа getline из iostream и fstream =( Так что
> придется обходиться DOS'овскими... Там же есть что-то
> такое? ;)
Не помню %-) Давно было. На самом деле можно попытаться подсунуть старому компилятору STL от нового - вдруг проглотит?.. Хотя сильно вряд ли - когда вышел Borland C++ 3.1, шаблоны только-только появились и даже не были в стандарте, если не ошибаюсь.
Есть еще одна мысль. Если ты не очень завязан на Borland (хотя если ты используешь conio.h... ну ладно), можешь попробовать пересесть на другой компилятор (современный, но не от Borland).

> Но все равно всем спасибо!!! Особенно тебе, Ktirf :))
Всегда пожалуйста :)

Тему закрыть не забудь :)
1  |  2 >>  »  




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach