https://man.liquidfiles.com
LiquidFiles Documentation

There's very few things that attract as many opinions in the IT security space as the password policy within a company. There are many, many different variants, and everyone seems to have a strict policy that their own password policy needs to be implemented across the board.

Instead of trying to adhere to every single implementation variant, LiquidFiles tries as usual to have a very pragmatic approach with a decent default policy and the ability to add your own using regular expression in Admin → Settings.

If this is not good enough for you, starting with v2.3.17, there's also another option of simply writing your own custom validation script. To make this work, you will need a production license, this is not something that is possible to test with a demo license.

On the LiquidFiles system, if there's a executable script in /usr/local/bin/validate_password it will be executed instead of the default server side password validation. A couple of things to note:

  • The client side will still use the regular expression or default checking. We assume that you will be having a password policy that is too complex to write in regular expression so client side validation doesn't really work anyway, and it can still provide a first level check.
  • The server side validation will be replaced by your script. They won't be checked in parallel.
  • You will have access to the environment variables PASSWORD, EMAIL and GROUP so that you can have different policies for different users or different groups if you want. Please note that all environment variables will be escaped using the shell escape method as described here: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellescape.
  • The script needs to send an exit code of zero (0) for any valid password, and nonzero (1 for instance) for any invalid password. If you output any string, this will be added in the interface as the error message if the result is nonzero. The output string will be silently discarded if the password was valid.
  • We won't be able to help you write a script for you to match your policy. Please get a programmer involved if you don't know how to do this yourself.

If we look at an example, please look at the following:

#!/bin/bash
#
# Installed as /usr/local/bin/validate_password
#
# Available environment variables:
#   $PASSWORD = the users password
#   $EMAIL = the users email
#   $GROUP = the users group they belong to, or will belong to
#
# Please note that then environment variables will be escaped 
# using the shellescape method as described here:
# http://www.ruby-doc.org/stdlib-1.9.3/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellescape
#
# Exit codes:
# 0: Everything is ok
# 1: Password is not permitted
#
# The text output will be listed as the password error
#
if [[ $GROUP == "System Administrators" ]]; then
 echo "Sysadmins never select bad passwords"
 exit 0
elif [[ $PASSWORD == $EMAIL ]]; then
 echo "You can't use your email as password"
 exit 1
elif [[ $PASSWORD == "password" ]]; then
 echo "You got to be joking!"
 exit 1
elif [[ `echo $PASSWORD | /usr/sbin/cracklib-check | egrep "\: OK$" | wc -l` -eq 0 ]]; then
 echo $PASSWORD | /usr/sbin/cracklib-check | awk '{for (i=2; i
      

This should obviously serve as an example of how to write the script, not as example of a good password policy. The script should be pretty self explanatory. And if we step through it step by step:

  • First check if the users group is "System Administrators" and if it is just permit the password (exit 0).
  • Check if the password is the same as the email address and don't permit it if it is.
  • Simple string checking if someone tries to use use the password "password".
  • The next example is probably the most interesting from a security perspective, where passwords are checked against the password database cracklib (http://cracklib.sourceforge.net), and if the password is not listed as OK, it will be blocked. The complex "awk" script simply removes the first word (the password in cleartext) from the output.
  • If nothing has blocked the password at this point, just allow it.

To test the password validation, the easiest is just to run some tests on the command line like:

[root@liquidfiles current]# env GROUP="System Administrators" EMAIL=a@x.com PASSWORD=password /usr/local/bin/validate_password; echo $?
Sysadmins never select bad passwords
0
[root@liquidfiles current]# env GROUP="x" EMAIL=a@x.com PASSWORD=a@x.com /usr/local/bin/validate_password; echo $?
You can't use your email as password
1
[root@liquidfiles current]# env GROUP="x" EMAIL=a@x.com PASSWORD=password /usr/local/bin/validate_password; echo $?
You got to be joking!
1
[root@liquidfiles current]# env GROUP="x" EMAIL=a@x.com PASSWORD=p@ssword /usr/local/bin/validate_password; echo $?
it is based on a dictionary word
1
[root@liquidfiles current]# env GROUP="x" EMAIL=a@x.com PASSWORD=r2mpelst1lstkin /usr/local/bin/validate_password; echo $?
All good
0

Every time you'll see a zero (0), the password would have been permitted. Every time you see a one (1), the password would have been blocked and the message would have been fed back to the user as the password error.

As you can see, you can now write as complex a policy as your company demands. If you want store user passwords (lets say you want to create a policy that users can't reuse the previous 5 passwords), the best way is to use a hash algorithm like SHA1 (in bash, you can run: echo $PASSWORD | sha1sum | awk '{print $1}' to get the password hash). You can then store the passwords somewhere in /var/data where the script will be able to write to, or possibly use something like a SQLite database to store the passwords. Please note that when the script executes, it's because the users password is about to be changed, if the script you write has an exit code of zero (0), it will be changed. The script is the final validation.

Even if the example here is written in bash, you can write in pretty much any language available on the system that you're familiar with. Such as bash, perl, ruby, python or c. Anything really that you can execute as in the example above and that can give exit codes of zero (0) or one (1) for valid/invalid passwords respectively.

Feel free to post more examples as comments.