Reputation: 251
I'm trying to create a program that obscures the characters entered when entering the password. But I still have a problem, as soon as I start the program, '*' characters are continuously written up to a segmentation fault. This is the code that I wrote and the behavior of the program after execution:
#include <stdio.h>
#include <curses.h>
#define ENTER 13
#define TAB 9
char pwd[100];
int main(){
int i = 0;
char ch;
printf("Enter your password. Hit ENTER to confirm.\n");
printf("Password:");
while(getch() != ENTER){
ch = getch();
pwd[i++] = ch;
printf("* \b");
}
if(ch == ENTER || ch == TAB){
pwd[i] = '\0';
}
printf("\n\nPassword:%s\nLength:%d\n\n", pwd, i);
return 0;
}
Upvotes: 1
Views: 358
Reputation: 16540
regarding:
while(getch() != ENTER){
ch = getch();
this gets 2 characters every pass through the loop. Not what you want. Suggest:
while( ( ch = getch() ) != ENTER ){
To avoid echoing the char when the user enters it:
You need to turn echo off
then for each char entered by the user, output a masking character, like *
since the array pwd[]
is only 100 characters long, need to limit the number of characters the user can enter to 99 (leaves room for the trailing NUL byte) Suggest:
WINDOW *mainwin;
mainwin = initscr(); /* start the curses mode with default window */
clear() /* clear the default window */
...
raw(); /* stop terminal driver from interpreting key strokes */
cbreak(); /* input chars without waiting for newline */
nodelay( mainwin, true); /* causes getch() to wait for a key rather than returning ERR */
keypad( mainwin, true ); /* program must handle all meta keys including newline */
noecho(); /* stop terminal echo while entering password */
size_t i = 0;
while( i < (sizeof( pwd ) -1) && ( ch = getch() ) != ENTER )
{
pwd[i] = ch;
i++;
printw( "*" );
refresh();
}
echo(); /* resume echoing characters on terminal */
keypad( mainwin, false ); /* stop passing keypad chars to program */
noraw(); /* terminal driver resumes interpreting key strokes */
pwd[i] = '\0'; /* NUL terminate the string */
...
endwin();
The above may be a bit of overkill.
due to several problems, suggest NOT using the C library function: getpass()
if you use the raw()
function, then the program will also need to handle backspace (and similar) characters from the user.
Upvotes: 0
Reputation: 6866
Looks like you're getting ERR
returned from getch()
.
That is not equal to ENTER
, so the loop is entered and repeated. Eventually, you run out of room in pwd
, but continue writing outside it. The segmentation fault means that you tried to write some address that is unwriteable.
You also have a bug in that you call getch()
twice per loop, which will give you trouble even after fixing the loop/segfault issue.
Upvotes: 0
Reputation: 13597
You are supposed to call initscr();
before you start using any ncurses methods. So, try doing this:
int main(){
int i = 0;
char ch;
initscr();
// ...
More information.
Upvotes: 2