不使用getpass(3)在C中获取密码?
我可以使用不使用getpass(3)在C中获取密码?,c,passwords,C,Passwords,我可以使用getpass()获取密码。然而,手册页上说: 此功能已过时。不要使用 它 以POSIX兼容方式从用户终端获取密码而不回显密码的当前方式是什么?[最初我说的是“可移植”,但我的目的是避免使用过时的函数。]您可以使用库读取标准输入,而无需将结果回显到屏幕上。(在获得任何输入之前调用noecho())。该库已存在多年,可在多种平台上使用(可以找到windows版本)在windows上,您可能可以使用所述的SetConsoleModeapi。根据说明,它已过时,因为: getpass()函数
getpass()
获取密码。然而,手册页上说:
此功能已过时。不要使用
它
以POSIX兼容方式从用户终端获取密码而不回显密码的当前方式是什么?[最初我说的是“可移植”,但我的目的是避免使用过时的函数。]您可以使用库读取标准输入,而无需将结果回显到屏幕上。(在获得任何输入之前调用
noecho()
)。该库已存在多年,可在多种平台上使用(可以找到windows版本)在windows上,您可能可以使用所述的SetConsoleMode
api。根据说明,它已过时,因为:
getpass()
函数不是线程安全的,因为它操作
全局信号状态
计划从X/Open CAE规范的未来版本中撤销getpass()
功能
这应该适用于linux/macosx,windows版本应该使用
#包括
#包括
#包括
int
主(内部argc,字符**argv)
{
标签、非标签的结构术语;
字符密码[64];
/*禁用回音*/
tcgetattr(文件号(stdin)和oflags);
nflags=标签数量;
nflags.c_lflag&=~ECHO;
nflags.c|lflag |=ECHONL;
if(tcsetattr(文件号(stdin)、TCSANOW和nflags)!=0){
佩罗尔(“tcsetattr”);
返回退出失败;
}
printf(“密码:”);
fgets(密码、sizeof(密码)、标准输入法);
密码[strlen(password)-1]=0;
printf(“您键入了“%s”\n”,密码);
/*恢复终端*/
if(tcsetattr(文件号(stdin)、TCSANOW和of标签)!=0){
佩罗尔(“tcsetattr”);
返回退出失败;
}
返回0;
}
尽管这是一个已经回答过的非常古老的问题,但以下是我一直在使用的内容(与公认的答案非常相似):
#包括
#包括
//
//以下是略作修改的版本,摘自:
// http://www.gnu.org/software/libc/manual/html_node/getpass.html
//
ssize\u t my\u getpass(字符*提示符,字符**lineptr,大小\u t*n,文件*流)
{
结构术语旧,新;
国际nread;
/*关闭回音功能,如果不能,则会失败*/
if(tcgetattr(文件号(流),&u旧)!=0)
返回-1;
_新=旧;
_new.c_lflag&=~ECHO;
if(tcsetattr(文件号(流)、TCSAFLUSH和&u新)!=0)
返回-1;
/*显示提示*/
如果(提示)
printf(“%s”,提示符);
/*读取密码*/
nread=getline(lineptr,n,stream);
/*拆下托架返回装置*/
如果(nread>=1&(*lineptr)[nread-1]=='\n')
{
(*lineptr)[nread-1]=0;
nread--;
}
printf(“\n”);
/*还原终端*/
(void)tcsetattr(文件号(流)、TCSAFLUSH和旧文件);
返回nread;
}
//
//测试线束-演示如何调用my_getpass()。
//
int main(int argc,char*argv[])
{
最大尺寸=255;
字符pwd[maxlen];
char*pPwd=pwd;//另一个简单的Windows解决方案。
包括“conio.h”
没有可移植的方法-这在很大程度上取决于您的平台。@Jerry,这不值得…尽管它是传统的,但这是最可移植的方法。对我来说,这似乎是最简单的方法。在尝试stdin之前,您应该先使用/dev/tty,就像使用管道一样,stdin将是管道内容,而不是终端输入。我会ldn不介意在使用字符密码[64]={0};或者如果它是可重入的password[strlen(password)-1]=0;
-这是非常错误的。password[strlen(password)-1]=0;
只有在新行存在时才会删除它,否则它会错误地删除密码的最后一个字符。password[strcspn](password,“\n”)]='\0'
。我制作了一个简单的curses应用程序(自从我使用curses以来,它已经过时了好几年),并发现当我使用initscr()时,它清除了屏幕。可能有一些方法可以解决这个问题,但快速阅读手册页后并不明显。它已从POSIX/Single UNIX(X/Open的继承者)中退出从2001年开始。这是一个怎样的答案?这真的应该是一个注释。我是古斯塔。这甚至可以让你从命令行输入密码;但是,如果你要这样做,你可能不想打印密码提示。
#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;
}
for (;;) {
int c = _getch();
switch (c)
{
case '\r':
case '\n':
case EOF:
_putch('\n');
break;
default:
_putch('*'); //mask
thePassword += char(c);
continue;
}
break;
}