[英]C command-line password input
I want to allow users to enter password using command-line interface. 我想允许用户使用命令行界面输入密码。 but I don't want to display this password on screen (or display "****"). 但我不想在屏幕上显示此密码(或显示“ ****”)。
How to do it in C? 用C怎么做? Thanks. 谢谢。
Update: 更新:
I'm working on Linux only. 我仅在Linux上工作。 So I don't actually care about Win or other systems. 因此,我实际上并不关心Win或其他系统。 I tried Lucas' solution and it worked fine. 我尝试了卢卡斯的解决方案,效果很好。 However, I still have another question: 但是,我还有另一个问题:
If this is a single process & single thread app, changing setting of termios affects different terminals? 如果这是一个单进程和单线程应用程序,那么更改termios的设置会影响不同的终端吗?
How about 1 process - multi threads, multi processes - multi threads? 1个进程-多线程,多进程-多线程怎么样?
Thanks very much. 非常感谢。
If you are using a UNIX environment something like this can turn off the ECHO of the command-line. 如果使用的是UNIX环境,则可能会关闭命令行的ECHO。
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#define SIZE 100
void getPassword(char password[])
{
static struct termios oldt, newt;
int i = 0;
int c;
/*saving the old settings of STDIN_FILENO and copy settings for resetting*/
tcgetattr( STDIN_FILENO, &oldt);
newt = oldt;
/*setting the approriate bit in the termios struct*/
newt.c_lflag &= ~(ECHO);
/*setting the new bits*/
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
/*reading the password from the console*/
while ((c = getchar())!= '\n' && c != EOF && i < SIZE){
password[i++] = c;
}
password[i] = '\0';
/*resetting our old STDIN_FILENO*/
tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}
int main(void)
{
char password[SIZE];
printf("please enter password\n");
getPassword(password);
printf("Do something with the password <<%s>>\n", password);
return 0;
}
The function getpass is now obsolete . 函数getpass现在已过时 。 Use termios . 使用termios 。
#include <termios.h>
#include <stdio.h>
void get_password(char *password)
{
static struct termios old_terminal;
static struct termios new_terminal;
//get settings of the actual terminal
tcgetattr(STDIN_FILENO, &old_terminal);
// do not echo the characters
new_terminal = old_terminal;
new_terminal.c_lflag &= ~(ECHO);
// set this as the new terminal options
tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal);
// get the password
// the user can add chars and delete if he puts it wrong
// the input process is done when he hits the enter
// the \n is stored, we replace it with \0
if (fgets(password, BUFSIZ, stdin) == NULL)
password[0] = '\0';
else
password[strlen(password)-1] = '\0';
// go back to the old settings
tcsetattr(STDIN_FILENO, TCSANOW, &old_terminal);
}
int main(void)
{
char password[BUFSIZ];
puts("Insert password:");
get_password(password);
puts(password);
}
For C/commandline/linux see: 对于C / commandline / linux,请参阅:
man getch
man noecho
see the coment in getch
about noecho
. 在getch
看到关于noecho
。 I've never tried this myself. 我自己从来没有尝试过。
In bash if you use read -s
it does not echo on the screen: 在bash中,如果您使用read -s
它不会在屏幕上回显:
> read -s x
<type something><enter>
> echo $x
<whatever you typed>
To do this in a portable way you will need to use a standardized or de-facto standard library. 为此,您将需要使用标准化或实际标准库。
See man 3 termios
and man 3 ncurses
. 参见man 3 termios
和man 3 ncurses
。
Here is a program that will work on Linux and other Unix systems... 这是一个可以在Linux和其他Unix系统上运行的程序...
#include <stdio.h>
int main(void) {
int f = open("/dev/tty", 0);
char s[100];
system("stty -echo > /dev/tty");
f >= 0 && read(f, s, sizeof s) > 0 && printf("password was %s", s);
system("stty echo > /dev/tty");
return 0;
}
A number of improvements are possible. 许多改进是可能的。 Using termios would probably be better, and it would avoid the fork and possible security issues of system(). 使用termios可能会更好,并且可以避免分叉和system()可能出现的安全问题。 Using standard I/O to read the password would probably be better. 使用标准I / O读取密码可能会更好。 (As written the typed newline would have to be deleted.) There is a getpass() function in Linux and some others however it is marked as "obsolete. Do not use it.". (按照书面要求,键入的换行符必须删除。)Linux和其他一些函数中有一个getpass()函数,但是将其标记为“过时。请勿使用它”。 It might be a good idea to deal with SIGTSTP. 处理SIGTSTP可能是一个好主意。
Overall, I might look for an existing solution that deals with all these little issues... 总的来说,我可能会寻找一个可以解决所有这些小问题的现有解决方案...
If you have access to the curses library, you can use noecho . 如果您有权访问curses库,则可以使用noecho 。 If you're using Microsoft's C compiler, you can use _getch . 如果您使用的是Microsoft的C编译器,则可以使用_getch 。 But afaik, both of these tie you to the console. 但是afaik,这两者都将您与控制台绑定在一起。 If you need to read stdin regardless of whether it comes from the console or a file or a piped command, you need to tell the operating system how it should handle the console . 如果您需要读取stdin而不管它是来自控制台还是来自文件或管道命令,则需要告诉操作系统应如何处理控制台 。
#include<conio.h>
#include<iostream>
using namespace std;
int main(){
char *pass = new char[20];
cout<<"Password :";
int i=0;
while( ( pass[i]=getch() ) != '\n' && pass[i] != '\r' && i<19 )
{putchar('*'); i++;}
pass[i]='\0';
cout<<endl;
if(strcmp("123456789",pass)==0 ) // do stuff
return 0;}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.