How to take hidden password from terminal in C/C++
Tags: cpp, programming, terminal, c
Published: 2023-01-10 21:48:13

Have you every wondered, In some terminal programs when they ask for password and you enter it, so either it does not display anything or displays __'**********'__ while typing. 

__So how these programs take passwords?__

The default input mode of terminal is echo, So as soon as we start typing any character in the terminal it show there simultaneously. But we can change this default behavior to do our job of taking the password from terminal without being it visible.

Here is a simple program that demonstrate how we can do this. `termios.h` is the header file where all the struct and function related to terminal are defined.

```c
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>

int getch() {
    int ch;
    // struct to hold the terminal settings
    struct termios old_settings, new_settings;
    // take default setting in old_settings
    tcgetattr(STDIN_FILENO, &old_settings);
    // make of copy of it (Read my previous blog to know 
    // more about how to copy struct)
    new_settings = old_settings;
    // change the settings for by disabling ECHO mode
    // read man page of termios.h for more settings info
    new_settings.c_lflag &= ~(ICANON | ECHO);
    // apply these new settings
    tcsetattr(STDIN_FILENO, TCSANOW, &new_settings);
    // now take the input in this mode
    ch = getchar();
    // reset back to default settings
    tcsetattr(STDIN_FILENO, TCSANOW, &old_settings);
    return ch;
}

int main(void) {
    char password[100];
    int i = 0;
    int ch;

    printf("Enter password: ");
    while ((ch = getch()) != '\n') {
        if (ch == 127 || ch == 8) { // handle backspace
            if (i != 0) {
                i--;
                printf("\b \b");
            }
        } else {
            password[i++] = ch;
            // echo the '*' to get feel of taking password 
            printf("*");
        }
    }
    password[i] = '\0';

    printf("\nYou entered password: %s\n", password);

    return 0;
}
```

__Output:__
```bash
Enter password: *****
You entered password: naman
```

Instead of writing this whole program we can either use inbuild function `getoass` define in `unistd.h` header to take password without echoing but we don't get much control here like echoing '*' while writing.


```c
#include <stdio.h>
#include <unistd.h>

int main(void) {
    char *password;

    password = getpass("Enter password: ");
    printf("You entered password: %s\n", password);

    return 0;
}
```

__Output:__
```bash
Enter password:
You entered password: naman
```

> **NOTE:** The man page of `getpass` says *function opens /dev/tty (the controlling terminal of the process), outputs the string prompt, turns  off  echoing,  reads  one line (the "password"), restores the terminal state and closes /dev/tty again.* which means that password will not be stored in the shell history.

> **NOTE:** Custom implementation of this program also does not store the password in the shell history even though it is taking input from `stdin`. The reason is that the `getch` function reads a character directly from the terminal without waiting for the user to press the enter key, so the password is not passed to the shell as a command.


Thank you ❤️ so much for reading this article. I'm also a student learning new things so If you find any mistakes or have any suggestions please let me know in the comments.

Also, consider sharing and giving a thumbs up If this post helps you in any way.