Advanced Bash Scripting – Part 1

Shell Script

Hello everyone, I’m planning to solve the problems in the Advanced Bash-Scripting Guide, say like one problem per week. Why am I doing this?

1. The problems there are very interesting.
2. Working in windows all the time, I feel I’m losing my shell scripting abilities. This will keep me updated.

The problem we are going to solve this week is “Testing Passwords”. The problem statement is as follows.

Write a script to check and validate passwords. The object is to flag “weak” or easily guessed password candidates.
A trial password will be input to the script as a command-line parameter. To be considered acceptable, a password must meet the following minimum qualifications:

1. Minimum length of 8 characters
2. Must contain at least one numeric character
3. Must contain at least one of the following non-alphabetic characters: @, #, $, %, &, *, +, -, =

Optional:
Do a dictionary check on every sequence of at least four consecutive alphabetic characters in the password under test. This will eliminate passwords containing embedded “words” found in a standard dictionary.
Enable the script to check all the passwords on your system. These probably do not reside in /etc/passwd.

The command I’m planning to use for this is grep, with a few for loop constructs and string operations.

Let’s check the constraints one by one.

#Minimum length of 8 characters
if [ ${#password} -lt 8 ]
then
  echo "$password: $weakString"
  return
fi

#Must contain at least one numeric character
if [ `echo $password | grep -c -E "[0-9]+"` -eq 0 ]
then
  echo "$password: $weakString"
  return
fi

#Must contain at least one of the following non-alphabetic characters: @, #, $, %, &, *, +, -, =
if [ `echo $password | grep -c -E "[@#$%&*=+-]+"` -eq 0 ]
then
  echo "$password: $weakString"
  return
fi

#Do a dictionary check on every sequence of at least four consecutive alphabetic characters in the password under test. This will eliminate passwords containing embedded "words" found in a standard dictionary.
for((i=4;i<=${#password};i++))
do
  for((j=0;j<=${#password}-$i;j++))
  do
    if [ `grep -c -E "^${password:$j:$i}$" dict.txt` -gt 0 ]
    then
      echo "$password: $weakString"
      return
    fi
  done
done

That's about it, we have checked all the constraints. Now, we will combine all the checks in one function and then we will pass all the command line parameters to this function one by one.

You can take a look at the final script here.

Can you make it any better or reduce the code size? Feel free to add it in the comments section.

6 thoughts on “Advanced Bash Scripting – Part 1

  1. Pingback: Siddharth
  2. Nice Series :) Something I can relate to :P

    Regarding this script, well you can check for special character check all in one go ! And also, should the dict checking be case sensitive or insensitive ?

    ~S

  3. He he :)

    Yeah, probably I could’ve added the special character check with the numeric character check, but wanted to keep the code clean. And not sure about the case sensitive check. Nothing was mentioned in the problem. I have coded it as case sensitive checking.

  4. One small suggestion for the last part check .. instead of having the inner loop on index and outer loop on the length , if they are swapped, the complexity will reduce in the worst case.. For each index, we start checking for lengths from 4 to ${#password} instead of checking all 4 letter substrings and all 5 letter and so on till ${#password} …

Leave a Reply

Your email address will not be published. Required fields are marked *


8 + five =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>