Encrypt password but use * when typing password

Hi,

I came across the following script for encrypting the password in this forum

#! /usr/bin/ksh
exec 4>/dev/tty
function getpass
{
        typeset prompt=$1
        typeset backspace=$(echo  \\b\\c)
        typeset enter=$(echo \\r\\c)
        typeset savesetting=$(stty -g)
        typeset keystroke password n i reading result
        n=0
        echo "${prompt}"\\c >&4
        stty -echo -icrnl -icanon min 1 time 0
        reading=1
        while ((reading)) ; do
                keystroke=$(dd bs=1 count=1 2>/dev/null)
                case $keystroke in
                $enter)
                        reading=0
                        ;;
                $backspace)
                        if ((n)) ; then
                                echo "${backspace} ${backspace}"\\c >&4
                                ((n=n-1))
                        fi
                        ;;
                *)
                        echo \*\\c >&4
                        data[n]=$keystroke
                        ((n=n+1))
                esac
        done
        stty "$savesetting"
        echo >&4
        result=""
        i=0
        while  ((i<n)) ; do
                result="${result}${data}"
                ((i=i+1))
        done
        echo $result
        return 0
}
final=$(getpass "password:")
echo the password is $final
exit 0

I copied the script and executed it. I executed in RHEL. But this script outputs as given below:

[root@netcool ncoadmin]# ./a.sh
password:\c
*\c
*\c
*\c
*\c
*\c
*\c

I was expecting I should get something like this

password: ********

meaning whatever the password I type it should be in asterix. But this script keeps on moving down when I press a single character.

Can someone help me in this regard.

Thanks
Dinesh

echo adds a newline, and doesn't understand escape sequences, try printf, which does understand escape sequences and doesn't add newlines.

I have no idea what \c is intended to do, though. That's not a valid escape sequence.

I've used \c in the past on AIX.

From man echo on AIX:

       \c
            Suppresses the new-line character that otherwise follows the final argument in the output. All characters following the \c sequence are ignored.

(of course now, I'd use printf!)

Your script worked for me on Solaris exactly as copied:

$ getpw
password:***
the password is efs
$ getpw
password:***********
the password is thisisatest
$

the \c means suppress the newline after printing the string.

I would put the escape sequence inside the quotes though so you don't need to worry about escaping the escape sequence which is where I think your issue is.

echo "testing\c"

Hi All,

Thanks for your replies.

I tried this on AIX, Solaris yes this works fine.

But on RHEL this does not work it outputs as I shown in my first post.

Any idea what should I do in RHEL, how to overcome this?

Thanks
Dinesh

You should also use the trap command to reset the stty settings if the script is interrupted while running. Otherwise, your terminal session will be left hosed if you interrupt it while it is waiting for input.

trap 'stty "$savesetting"' 2 3 9 15

the command in the single quotes will be executed if any of those signals are received. Some common signals:

SIGHUP (1) Hang up.
SIGINT (2) Interrupt from keyboard. Issued if you press ^C.
SIGQUIT (3) Quit from keyboard. Issued if you press ^D.
SIGFPE (8) Floating point exception.
SIGKILL (9) Kill signal.
SIGTERM (15) Terminate. Cause the program to quit gracefully
SIGCHLD (17) Child terminate.

Try echo -e, Linux won't understand \c without it. Or echo -n without the \c, to tell echo not to print a newline.

I really do think printf would be better, since newlines (or the lack of them) are a standard, portable feature of it -- should work the same on UNIX or Linux, shell builtin or external.

$ printf "hello\n"
hello
$ printf "hello"
hello$

Hi,

Thanks for all the replies.

I will try to work on it.

Thanks
Dinesh

---------- Post updated at 10:19 AM ---------- Previous update was at 02:04 AM ----------

Hi

I am able to solve the issue of getting the password in '*' and displaying it. But I landed up in another issue. When I press backspace it does not go back and erase the character but instead it puts a '[]' type

password:********
the password is wel[]come

In the above I typed a backspace near letter 'l' but it has put a box like symbol.

But this problem goes if I type ^H character

[ncoadmin@netcool ~]$ ./a.sh
password:******
the password is wecome

The modified code looks like this

#!/bin/sh
exec 4>/dev/tty
function getpass
{
        typeset prompt=$1
        typeset backspace=$(echo -en \\b\\c)
        typeset enter=$(echo -e \\r\\c)
        typeset savesetting=$(stty -g)
        typeset keystroke password n i reading result
        n=0
        echo -e "${prompt}"\\c >&4
        stty -echo -icrnl -icanon min 1 time 0
        reading=1
        while ((reading)) ; do
                keystroke=$(dd bs=1 count=1 2>/dev/null)
                case $keystroke in
                $enter)
                        reading=0
                        ;;
                $backspace)
                        if ((n)) ; then
                                echo -e "${backspace} ${backspace}"\\c >&4;
                                #stty erase '^H'
                                ((n=n-1))
                        fi
                        ;;
                *)
                        echo -e \*\\c >&4
                        data[n]=$keystroke
                        ((n=n+1))
                esac
        done
        stty "$savesetting"
        echo -e >&4
        result=""
        i=0
        while  ((i<n)) ; do
                result="${result}${data}"
                ((i=i+1))
        done
        echo -e $result
        return 0
}
final=$(getpass "password:")
echo -n  the password is $final
exit 0

Please let me know what should I modify so that when the user presses the backspace I should erase a character

Thanks
Dinesh

You don't need to change all your echo commands to "echo -e" or "printf" just set the following at the top of your script (line 1):

shopt -s xpg_echo

For backspace issue just use

stty erase ^\?

perhaps this should be in your .profile or .bash_profile

Hi

I tried to modify and run the code but it does not seem to work. The backspace works only if I press the ctrl+H key only. It does not recognize when I press the 'backspace' key.

Just wanted to know what else should I modify? So, that the backspace key works.

Thanks
Dinesh