Получение пароля в C без использования getpass (3)?
Я мог бы использовать getpass()
, чтобы получить пароль. Однако на главной странице написано:
Эта функция устарела. Не использовать оно.
Каков текущий способ получить пароль от терминала пользователя, не повторяя его, в POSIX-совместимом способе? [Первоначально я сказал "переносно", но мое намерение состояло в том, чтобы избежать использования устаревшей функции.]
5 ответов:
Это должно работать на Linux/MacOSX она называется, версию Windows должны использовать получить/установить ConsoleMode
#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; }
Хотя это очень старый вопрос, на который уже был дан ответ, вот что я использую (что очень похоже на принятый ответ):
#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; }
Согласно документации университета Милуоки он устарел, потому что:
Функция
getpass()
не является потокобезопасной, поскольку она манипулирует состояние глобального сигнала.Функцию
getpass()
планируется изъять из будущей версии спецификации X/Open CAE.