Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Получение пароля на C без использования getpass (3)?

Автор вопроса: Jerry PennerОтветов: 6

Я мог бы использовать getpass(), чтобы получить пароль. Однако на странице руководства говорится:

Эта функция устарела. Не используйте его.

Каков текущий способ получить пароль с пользовательского терминала без его повторения в соответствии с POSIX? [Первоначально я сказал "переносимо", но я хотел избежать использования устаревшей функции.]

  • Портативного способа нет - это сильно зависит от вашей платформы. 29.07.2009
  • @ Джерри, оно того не стоит ... хотя это НАСЛЕДИЕ, это самый портативный способ сделать это. Michael Aaron Safyan 14.04.2010

cpasswords

Ответы

Ответ 1 · рейтинг 17 · dfa

это должно работать на linux/macosx, версия для Windows должна использовать Get /Установить режим консоли

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

int
main(int argc, char **argv)
{
    struct termios oflags, nflags;
    char password[64];

    /* disabling echo */
    tcgetattr(fileno(stdin), &oflags);
    nflags = oflags;
    nflags.c_lflag &= ~ECHO;
    nflags.c_lflag |= ECHONL;

    if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    printf("password: ");
    fgets(password, sizeof(password), stdin);
    password[strlen(password) - 1] = 0;
    printf("you typed '%s'\n", password);

    /* restore terminal */
    if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    return 0;
}

Ответ 2 · рейтинг 5 · indy

Вы можете использовать библиотеку ncurses для чтения из стандартного ввода без повторения результатов. на экран. (Позвоните noecho(), прежде чем получить какие-либо данные). Библиотека существует уже много лет и работает на самых разных платформах (версию для Windows можно найти здесь а>)

Ответ 3 · рейтинг 4 · Vanessa Deagan

Несмотря на то, что это очень старый вопрос, на который уже был дан ответ, вот что я использовал (что очень похоже на принятый ответ):

#include <termios.h>
#include <cstdio>

//
// The following is a slightly modifed version taken from:
// http://www.gnu.org/software/libc/manual/html_node/getpass.html
//
ssize_t my_getpass (char *prompt, char **lineptr, size_t *n, FILE *stream)
{
    struct termios _old, _new;
    int nread;

    /* Turn echoing off and fail if we can’t. */
    if (tcgetattr (fileno (stream), &_old) != 0)
        return -1;
    _new = _old;
    _new.c_lflag &= ~ECHO;
    if (tcsetattr (fileno (stream), TCSAFLUSH, &_new) != 0)
        return -1;

    /* Display the prompt */
    if (prompt)
        printf("%s", prompt);

    /* Read the password. */
    nread = getline (lineptr, n, stream);

    /* Remove the carriage return */
    if (nread >= 1 && (*lineptr)[nread - 1] == '\n')
    {
        (*lineptr)[nread-1] = 0;
        nread--;
    }
    printf("\n");

    /* Restore terminal. */
    (void) tcsetattr (fileno (stream), TCSAFLUSH, &_old);

    return nread;
}

//
// Test harness - demonstrate calling my_getpass().
//
int main(int argc, char *argv[])
{
    size_t maxlen = 255;
    char pwd[maxlen];
    char *pPwd = pwd; // <-- haven't figured out how to avoid this.

    int count = my_getpass((char*)"Enter Password: ", &pPwd, &maxlen, stdin);

    printf("Size of password: %d\nPassword in plaintext: %s\n", count, pwd);

    return 0;
}

Ответ 4 · рейтинг 1 · Brian

В Windows вы, вероятно, можете использовать SetConsoleMode API, описанный здесь а>.

Ответ 5 · рейтинг 1 · Kredns

Согласно документации Университета Милуоки, он устарел. так как:

Функция getpass() не является потокобезопасной, поскольку она манипулирует глобальным состоянием сигнала.

Планируется, что функция getpass() будет исключена из будущей версии спецификации X/Open CAE.

Ответ 6 · Marius Matioc

Еще одно простое решение для Windows. Включить "conio.h"

  for (;;) {
  int c = _getch();
  switch (c)
  {
  case '\r':
  case '\n':
  case EOF:
    _putch('\n');
    break;

  default:
    _putch('*'); //mask
    thePassword += char(c);
    continue;
  }
  break;
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы