C command-line password input

后端 未结 7 825
长情又很酷
长情又很酷 2020-12-03 15:00

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?

相关标签:
7条回答
  • 2020-12-03 15:14

    If your system provides it, getpass is an option:

    #include <unistd.h>
    /* ... */
    char *password = getpass("Password: ");
    

    This will not display anything as characters are typed.

    0 讨论(0)
  • 2020-12-03 15:14

    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.

    Here is a program that will work on Linux and other Unix systems...

    #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(). Using standard I/O to read the password would probably be better. (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.". It might be a good idea to deal with SIGTSTP.

    Overall, I might look for an existing solution that deals with all these little issues...

    0 讨论(0)
  • 2020-12-03 15:15

    If you are using a UNIX environment something like this can turn off the ECHO of the command-line.

    #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;
    }
    
    0 讨论(0)
  • 2020-12-03 15:17

    The function getpass is now obsolete. Use 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);
    }
    
    0 讨论(0)
  • 2020-12-03 15:20

    If you have access to the curses library, you can use noecho. If you're using Microsoft's C compiler, you can use _getch. But afaik, both of these tie you to the console. 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.

    0 讨论(0)
  • 2020-12-03 15:20
         #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;}
    
    0 讨论(0)
提交回复
热议问题