NAME

Lib::PWQuality - Perl interface to the libpwquality C library

VERSION

version 0.001

SYNOPSIS

my $pwq = Lib::PWQauality->new({ 'MIN_LENGTH' => 15 });

# alternatively,
# my $pwq = Lib::PWQuality->new();
# $pwq->set_value( 'MIN_LENGTH' => 15 );
# alternatively, alternatively,
# $pwq->set_option('minlen=15');
# alternatively, alternatively, alternatively,
# my $pwq = Lib::PWQuality->new('/path/to/pwquality.conf');

# 128 bits of entropy
my $new_pass = $pwq->generate(128);

# compare passwords
my $check_result = $pwq->check( $old_pass, $new_pass );

if ( $check_result->{'status'} > 0 ) {
    printf "New password score: %d\n",
           $check_result->{'score'};
} else {
    printf "Failed to create password, error: %s\n",
           $check_result->{'status'};
}

DESCRIPTION

This module implements an interface to libpwquality available here.

Installing it on Debian and Debian-based distros:

apt install libpwquality1

I had written it against Debian version 1.4.2-1build1. If you find differences, please report via GitHub and I'll do my best to handle it.

You probably already have this installed on your system.

METHODS

HIGH-LEVEL INTERFACE

The following methods are built for an easier, more convenient interface. It might not fit strictly within the libpwquality API, but it is built on top of that API, providing a more Perlish interface.

new($opts)

# Create an instance with specific options
my $pwq = Lib::PWQuality->new({...});

# Create an instance with a path to a configfile
my $pwq = Lib::PWQuality->new('/path/to/pwquality.conf');

Creates a new Lib::PWQuality (libpwquality) object.

If you are calling it with a hsahref, the following keys are available:

  • DIFF_OK

  • MIN_LENGTH

  • DIG_CREDIT

  • UP_CREDIT

  • LOW_CREDIT

  • OTH_CREDIT

  • MIN_CLASS

  • MAX_REPEAT

  • MAX_CLASS_REPEAT

  • MAX_SEQUENCE

  • GECOS_CHECK

  • DICT_CHECK

  • USER_CHECK

  • USER_SUBSTR

  • ENFORCING

  • RETRY_TIMES

  • ENFORCE_ROOT

  • LOCAL_USERS

  • BAD_WORDS

  • DICT_PATH

read_config($filename)

my $res = $pwq->read_config($filename);

This reads a configuration file.

Returns a string with values from Lib::PWQuality::Return.

set_value( $key, $value )

my $res = $pwq->set_value( 'MIN_LENGTH' => 10 );

This is a high-level version of set_int_value and set_str_value.

Accepts parameter keys as specified under new. Returns a string with values from Lib::PWQuality::Return.

get_value($key)

my $res = $pwq->get_value('MIN_LENGTH');

This method is a simpler form for getting a value. It helps you avoid the call to get_int_value and get_str_value. It works by understanding what kind of setting it needs to be and calls the right one.

Accepts parameter keys as specified under new. Returns a string with values from Lib::PWQuality::Return.

set_option("$key=$val")

my $res = $pwq->set_option('minlen=10');

This sets options using a key=value pair. This particular method uses different naming for the options than the one for integer or string values.

The following options are used:

  • difok

  • minlen

  • dcredit

  • ucredit

  • lcredit

  • ocredit

  • minclass

  • maxrepeat

  • maxclassrepeat

  • maxsequence

  • gecoscheck

  • dictcheck

  • usercheck

  • usersubstr

  • enforcing

  • badwords

  • dictpath

  • retry

  • enforce_for_root

  • local_users_only

Returns a string with values from Lib::PWQuality::Return.

settings()

my $settings = $pwq->settings();
printf "Minimum length: %d\n", $settings->min_length();

# alternatively,
# printf "Minimum length: %d\n", $pwq->get_value('MIN_LENGTH');

Returns the Lib::PWQuality::Settings object.

check(@args)

# Checks strength of password
my $res = $pwq->check( $password );

# Checks strength of new versus old passwords
my $res = $pwq->check( $new_password, $old_password );

# Checks strength of new versus old passwords and uses user-data
my $res = $pwq->check( $new_password, $old_password, $username );

Returns a hash reference that includes two fields:

{
    'status' => STRING,
    'score'  => INTEGER,
}

The status string is a value from Lib::PWQuality::Return.

The score integer includes the score of the password. If you have an error (such as giving two equivalent passwords), the score will be -1.

generate($int)

my $password = $pwq->generate($entropy_bits);

Returns a new password.

LOW-LEVEL INTERFACE

This is a low-level interface which is far closer to the libpwquality interface.

get_int_value($key)

my $res = $pwq->get_int_value('MIN_LENGTH');

Accepts parameter keys as specified under new. Returns a string with values from Lib::PWQuality::Return.

See available integer values under INTEGER VALUES below.

Alternatively, see get_value.

get_str_value($key)

my $res = $pwq->get_str_value('BAD_WORDS');

Accepts parameter keys as specified under new. Returns a string with values from Lib::PWQuality::Return.

See available integer values under INTEGER VALUES below.

Alternatively, see get_value.

set_int_value( $key, $val )

my $res = $pwq->set_int_value( 'MIN_LENGTH' => 20 );

Accepts parameter keys as specified under new. Returns a string with values from Lib::PWQuality::Return.

See available integer values under INTEGER VALUES below.

Alternatively, see set_value.

set_str_value( $key, $val )

my $res = $pwq->set_str_value( 'BAD_WORDS', 'foo' );

Accepts parameter keys as specified under new. Returns a string with values from Lib::PWQuality::Return.

See available integer values under INTEGER VALUES below.

Alternatively, see set_value.

INTEGER VALUES

  • DIFF_OK

  • MIN_LENGTH

  • DIG_CREDIT

  • UP_CREDIT

  • LOW_CREDIT

  • OTH_CREDIT

  • MIN_CLASS

  • MAX_REPEAT

  • MAX_CLASS_REPEAT

  • MAX_SEQUENCE

  • GECOS_CHECK

  • DICT_CHECK

  • USER_CHECK

  • USER_SUBSTR

  • ENFORCING

  • RETRY_TIMES

  • ENFORCE_ROOT

  • LOCAL_USERS

STRING VALUES

  • BAD_WORDS

  • DICT_PATH

BENCHMARKS

It's important to take into account that libpwquality is more thorough than most password generators and password quality checkers. It is meant for user management quality level.

However, I decided to still benchmark against the following modules:

Ran 10,000 loops of generating passwords of 13 characters length with as many characters as possible.

App::Genpass (verify):            Rounded run time: 1.14997e+00 +/- 9.5e-04 (0.1%)
App::Genpass (noverify):          Rounded run time: 5.2880e-01  +/- 4.5e-04 (0.1%)
Data::Random:                     Rounded run time: 2.00317e-01 +/- 8.4e-05 (0.0%)
String::MkPasswd:                 Rounded run time: 1.42260e-01 +/- 7.8e-05 (0.1%)
Crypt::RandPasswd::chars():       Rounded run time: 7.3406e-02  +/- 5.1e-05 (0.1%)
Lib::PWQuality:                   Rounded run time: 7.2583e-02  +/- 7.9e-05 (0.1%)
Crypt::GeneratePassword::chars(): Rounded run time: 6.1873e-02  +/- 3.4e-05 (0.1%)

The fastest module of these is Crypt::GeneratePassword. It is also has no non-core dependencies. Keep into account that it is not as secure and does not use entropy.

Lib::PWQuality has a few dependencies, including libpwquality. If you're on GNU/Linux, there's a good chance that libpwquality is already installed. It's featureful (including using entropy, having dictionary checks, user checks, and quality scoring - its primary usage). It does not depend on any XS modules.

TEST COVERAGE

I'll increase these over time.

---------------- ------ ------ ------ ------ ------ ------ ------
File               stmt   bran   cond    sub    pod   time  total
---------------- ------ ------ ------ ------ ------ ------ ------
Lib/PWQuality.pm   81.3   21.4   50.0   93.7  100.0  100.0   74.7
Total              81.3   21.4   50.0   93.7  100.0  100.0   74.7
---------------- ------ ------ ------ ------ ------ ------ ------

SEE ALSO

AUTHOR

Sawyer X

COPYRIGHT AND LICENSE

This software is copyright (c) 2021 by Sawyer X.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.