2009-11-23 9 views
12

Quiero permitir que los usuarios ingresen la contraseña mediante la interfaz de línea de comandos. pero no quiero mostrar esta contraseña en la pantalla (o mostrar "****").C entrada de contraseña de la línea de comando

¿Cómo hacerlo en C? Gracias.

Actualización:

Estoy trabajando solo en Linux. Entonces realmente no me importa Win u otros sistemas. Intenté la solución de Lucas y funcionó bien. Sin embargo, todavía tengo otra pregunta:

  1. Si se trata de una sola aplicación hilo único proceso &, cambiar la configuración de termios afecta a diferentes terminales?

  2. ¿Qué tal 1 proceso - multi hilos, multi procesos - multi hilos?

Muchas gracias.

+7

http://www.linux.com/learn/docs/man/3177-getpass3 – sambowry

+0

Qué consola y sistema operativo está usted? En la mayoría de los casos, la entrada del usuario se repetirá en la línea de comandos. Esto se puede cambiar, pero dependerá de la plataforma. – Lucas

+2

duplicado: http://stackoverflow.com/questions/1413445/read-a-password-from-stdcin –

Respuesta

2

Para C/comandos/Linux, véase:

man getch 
man noecho 

ver la coment en getch sobre noecho. Nunca lo intenté yo mismo.

En bash si utiliza read -s que no hace eco en la pantalla:

> read -s x 
<type something><enter> 
> echo $x 
<whatever you typed> 
+0

Upvoted para la filosofía de RTFM y la pista cruzada de la plataforma. – conradkdotcom

16

Si el sistema le proporciona, getpass es una opción:

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

Esto no mostrará nada como caracteres están tipeados

2

Para hacer esto de forma portátil, necesitará utilizar una biblioteca estándar estandarizada o de facto.

Ver man 3 termios y man 3 ncurses.

Aquí es un programa que funcione en Linux y otros sistemas Unix ... son posibles

#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; 
} 

una serie de mejoras. Usar termios probablemente sería mejor, y evitaría el fork y posibles problemas de seguridad del sistema(). Usar E/S estándar para leer la contraseña probablemente sería mejor. (Según lo escrito, la nueva línea debe ser eliminada.) Hay una función getpass() en Linux y en otras, pero está marcada como "obsoleta. No la use". Puede ser una buena idea tratar con SIGTSTP.

En general, puede ser que busque una solución existente que se ocupa de todos estos pequeños problemas ...

1

Si tiene acceso a la biblioteca maldiciones, puede utilizar noecho. Si está utilizando el compilador de C de Microsoft, puede usar _getch. Pero afaik, ambos te atan a la consola. Si necesita leer stdin sin importar si proviene de la consola o un archivo o un comando canalizado, necesita decirle al sistema operativo cómo debería handle the console.

9

Si está utilizando un entorno UNIX, algo así puede apagar el ECHO de la línea de comandos.

#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
 #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;} 
2

El getpass función es ahora 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); 
} 
Cuestiones relacionadas