Ayush Kumar
Ayush Kumar

Reputation: 11

masking password input in windows terminal in C

I am on Windows and have tried the following code to mask password input:

#include <stdio.h>
#include <conio.h>
int main() {
    int i = 0;
    char ch, password[13];
    printf("\nEnter Password (Upto 12 chars.): ");
    while (i < 12) {
        ch = getch();
        if (ch == ' ') {
            --i;
        } else if (ch == '\b') {
            printf("\b \b");
            i -= 2;
        } else if (ch == '\r')
            break;
        else {
            password[i] = ch;
            printf("*");
        }
        ++i;
    }
    password[i] = '\0';
    printf("\nPassword: %s",password);
    return 0;
}

The problem with above code is that when I have inputted no characters and I press backspace then the printed string Enter Password (Upto 12 chars.): gets its characters erased one by one. This I was able to work around by doing this Enter Password (Upto 12 chars.):\n and now it won't delete its characters. But there is another problem and that is whenever I try to close the terminal by pressing Alt+F4 the two keystrokes get considered input by getch() and I get two characters returned and displayed. I know it is my fault as the else part takes anything except \r,\b and white-space but I want help fixing it.

What I want is to be able to mask password input without any of the above problems. I have used MySQL Command-line client before and it asks for password input just fine. Anything like that or close to that would be appreciated.

I should mention this is for a University project.

Any help is appreciated

Upvotes: 0

Views: 878

Answers (1)

Ayush Kumar
Ayush Kumar

Reputation: 11

I fixed my own code. Took some inspiration from some old C++ code (not copy pasta).

It ignores whitespace, Esc key, function and arrow keys, works properly on backspace, and breaks out of the loop on hitting Tab or Enter. And now it doesn't delete characters from printf() string when hitting backspace on empty input.

The trick is to only assign input when all other if and else if conditions are not met and increment the counter in that else block only. And then when the loop ends put a '\0' at the last index of the string.

Here is the code:

#include <conio.h>
#include <stdio.h>
#define PASSWORD_LENGTH 12
int main() {
    int i = 0;
    char password[PASSWORD_LENGTH + 1];
    int ch;
    printf("\nEnter Password (Upto 12 chars.): ");
    while (i < PASSWORD_LENGTH) {
        ch = getch();
        if (ch == ' ' || ch == 27) {
            continue;
        } else if (ch == '\b') {
            if (i > 0) {
                printf("\b \b");
                --i;
            } else {
                continue;
            }
        } else if (ch == '\r' || ch == '\t') {
            break;
        } else if (ch == 0 || ch == 224) {
            ch = getch();
            continue;
        } else {
            password[i++] = ch;
            printf("*");
        }
    }
    password[i] = '\0';
    printf("\n,%s,", password); //this can be removed as it is only for displaying output
    return 0;
}

Upvotes: 1

Related Questions