Introduction to Linux - A Hands on Guide | Linux Bible | Linux From Scratch | A Newbie's Getting Started Guide to Linux | Linux Command Line Cheat Sheet | More Linux eBooks



Sunday, 2 August 2015

How To: Check if Username and Password are Valid using Bash Script

It's time to create a bash script that will take inputs - Username and Password, from the user and validate if the username-password combination is correct. There will be two essential steps involved in this script- check if username is valid and in case username is valid, check if password associated with that username is valid.



Let's start scripting!

1. Check if username is valid

This, surely, is the easier part of the script. Validating a user is very straight-forward, as you can use id command with option -u or read /etc/passwd (using 'grep' command) file to do so (Read about /etc/passwd file format here). If the exit status is "0", then it's a valid user, else it's not. For those who are new to bash scripting- Exit status can be checked using echo $?.

Let's check the validity of the user 'mandar'

MyLinuxBox root ~ > grep mandar /etc/passwd
mandar:x:500:500:Mandar Shinde:/home/mandar:/bin/bash

MyLinuxBox root ~ > id -u mandar
500
MyLinuxBox root ~ > echo $?
0

MyLinuxBox root ~ > grep -w mandar /etc/passwd
mandar:x:500:500:Mandar Shinde:/home/mandar:/bin/bash
MyLinuxBox root ~ > echo $?
0
In the first command, we made sure whether user 'mandar' exists and the same is assured by checking the exit status of the id -u mandar and grep -w "mandar" /etc/passwd command.

Lets check if there is any user 'shinde' (there isn't any).

MyLinuxBox root ~ > id -u shinde
id: shinde: No such user
MyLinuxBox root ~ > echo $?
1

MyLinuxBox root ~ > grep -w shinde /etc/passwd
MyLinuxBox root ~ > echo $?
1
And, exit status of those commands say the same.

2. Check if Password is valid

Now, let's suppose that, the username is valid and next step will be verifying the password. If you had read our article on /etc/shadow file format, you would have understood what I will be explaining here.

This file stores the passwords in encrypted format, for every user, on a separate line. Besides the hashed passwords, it stores other details also, from which we need to extract the password for comparison. /etc/shadow stores these details delimited with a colon (:) as below:

mandar:$6$5H0QpwprRiJQR19Y$bXGOh7dIfOWpUb/Tuqr7yQVCqL3UkrJns9.7msfvMg4ZO/PsFC5Tbt32PXAw9qRFEBs1254aLimFeNM8YsYOv.:16431:0:99999:7:::
mysql:!!:16550::::::
nagios:$6$P9zn0KwR$tgfvvFWJJ5FKmoXiP5rXWOjwoEBOEoAuBi3EphRbJqqjWYvhEM2wa67L9XgQ7W591FxUNklkDIQsk4kijuhE50:16632:0:99999:7:::
So, in order to extract the password from the line, we'll have to use cut command, combining with 'grep' command as below:

MyLinuxBox root ~ > grep -w mandar /etc/shadow | cut -d: -f2
$6$5H0QpwprRiJQR19Y$bXGOh7dIfOWpUb/Tuqr7yQVCqL3UkrJns9.7msfvMg4ZO/PsFC5Tbt32PXAw9qRFEBs1254aLimFeNM8YsYOv.
This is the original hashed password stored in /etc/shadow file. Read /etc/shadow file format for more details on how encrypted passwords are stored in this file.

The Encrypted Password

The field #2 in each line entry is the encrypted password. But, how this password is generated, we'll learn in this portion of the article. Let's just rewrite the encrypted password here-

$6$5H0QpwprRiJQR19Y$bXGOh7dIfOWpUb/Tuqr7yQVCqL3UkrJns9.7msfvMg4ZO/PsFC5Tbt32PXAw9qRFEBs1254aLimFeNM8YsYOv.

Let's break this encrypted password in some parts, across the dollar ($) sign, to understand it better.

$6$5H0QpwprRiJQR19Y$bXGOh7dIfOWpUb/Tuqr7yQVCqL3UkrJns9.7msfvMg4ZO/PsFC5Tbt32PXAw9qRFEBs1254aLimFeNM8YsYOv.
|1|-------2--------|-----------------------------------------3--------------------------------------------|
1. Hash Algorithm: This field denotes the hashing algorithm used to create the hashed password. The digit 6 describes that, SHA-512 algorithm is used, in this case. Some more of them are enlisted below:

--------------------
| 1  | MD5         |
--------------------
| 2  | Blowfish    |
--------------------
| 2a | eksBlowfish |
--------------------
| 5  | SHA-256     |
--------------------
| 6  | SHA-512     |
--------------------
2. Salt Value: Salt values are used to make the hash value stronger. These are the random type of data that is used to combine with the original password and then the hashed version of that is used as the encrypted password.
3. Password: This field stores the hashed version of the combination of original password and salt value.

Considering that user has provided the password, say mandar, we will try to create hashed value using the password entered by the user, the salt value (6) and the hashing algorithm (SHA-512) as below:

Syntax of the command is as follows:

perl -e 'print crypt("<PASSWORD>","\$<HASH-ALGO>\$<SALT-VALUE>\$") . "\n"'
In our case,
<HASH-ALGO> = 6
<PASSWORD> = mandar
<SALT-VALUE> = 5H0QpwprRiJQR19Y
Lets run the command now.

MyLinuxBox root ~ > perl -e 'print crypt("mandar","\$6\$5H0QpwprRiJQR19Y\$") . "\n"'
$6$5H0QpwprRiJQR19Y$bXGOh7dIfOWpUb/Tuqr7yQVCqL3UkrJns9.7msfvMg4ZO/PsFC5Tbt32PXAw9qRFEBs1254aLimFeNM8YsYOv.
This is the password that we've generated. If it matches with the password stored in /etc/shadow file, then we can confirm that the password entered by the user is correct.

Bash Script:

#!/bin/bash

read -p "Enter the Username: " USERNAME

id -u $USERNAME > /dev/null
if [ $? -ne 0 ]
then
        echo "User $USERNAME is not valid"
        exit 1
else
        echo "Enter the Password:"
        read -s PASSWD
        export PASSWD
        ORIGPASS=`grep -w "$USERNAME" /etc/shadow | cut -d: -f2`
        export ALGO=`echo $ORIGPASS | cut -d'$' -f2`
        export SALT=`echo $ORIGPASS | cut -d'$' -f3`
        GENPASS=$(perl -le 'print crypt("$ENV{PASSWD}","\$$ENV{ALGO}\$$ENV{SALT}\$")')
        if [ "$GENPASS" == "$ORIGPASS" ]
        then
                echo "Valid Username-Password Combination"
                exit 0
        else
                echo "Invalid Username-Password Combination"
                exit 1
        fi
fi
Successful Check:

MyLinuxBox root ~ > ./usrpasschk.sh
Enter the Username: mandar
Enter the Password:
Valid Username-Password Combination
Unsuccessful Check-1:

MyLinuxBox root ~ > ./usrpasschk.sh
Enter the Username: mandar
Enter the Password:
Invalid Username-Password Combination
Unsuccessful Check-2:

MyLinuxBox root ~ > ./usrpasschk.sh
Enter the Username: shinde
id: shinde: No such user
User shinde is not valid
For any suggestions, please write in the comments section below.

2 comments:

  1. Nice, however works only with stand-alone systems.
    When ldap connected - wont't work.
    Consider getent command to retreive proper information.

    ReplyDelete
  2. you may want to look at the getent command as well, rather than grub through /etc/passwd and /etc/shadow directly

    ReplyDelete