1 %%%-------------------------------------------------------------------
2 %%% Created : 1 Dec 2006 by Tobbe <tobbe@tornkvist.org>
3 %%% Desc. : A (pro-active) password checker.
5 %%% @author Torbjörn Törnkvist <tobbe@tornkvist.org>
7 %%% @doc <b>passwd_checker</b> is a pro-active password checker.
8 %%% It makes use of a tiny port program that uses cracklib.
10 %%% Download the dictionaries you want to use, e.g see:
12 %%% http://www.cotse.com/tools/wordlists.htm
14 %%% Then rebuild the dictionary, on Gentoo:
16 %%% create-cracklib-dict /usr/share/dict/*
20 %%% mkdict /usr/share/dict/* | packer /usr/lib/cracklib_dict
22 %%% On Ubuntu/Debian, see the man page for cracklib. You'll
23 %%% probably need to set the environment variable CRACKLIB_DICTPATH
24 %%% to: CRACKLIB_DICTPATH=/var/cache/cracklib/cracklib_dict
28 %%% http://gdub.wordpress.com/2006/08/26/using-cracklib-to-require-stronger-passwords/
32 %%%-------------------------------------------------------------------
33 -module(passwd_checker
).
35 -export([check
/1, check
/2, format
/1]).
37 -include("../include/passwd_checker.hrl").
40 cracklib_dict_path() -> "/usr/lib/cracklib_dict".
43 %%% @doc Textual error messages.
45 format(?PWD_CHK_TOO_SHORT
) -> "too short"; % Should be gettext'ified when needed...
46 format(?PWD_CHK_DICTIONARY
) -> "too common";
47 format(_
) -> "not secure enough".
50 %%% @doc Check if the password is good enough.
51 %%% By setting the environment variable CRACKLIB_DICTPATH to the
52 %%% full path name + filename prefix of the cracklib dictionary
53 %%% database, it will override the default in cracklib_dict_path/0.
56 case os:getenv("CRACKLIB_DICTPATH") of
57 Path
when list(Path
) ->
60 check(Passwd
, cracklib_dict_path())
64 %%% @doc Check if the password is good enough.
65 %%% Specify the path to the cracklib dictionaries.
67 check(Passwd
, CrackDictPath
) ->
68 PrivDir
= code:priv_dir(yfront
),
69 Cmd
= PrivDir
++"/passwd_checker "++Passwd
++" "++CrackDictPath
,
72 Error
-> {error
, analyse_string(Error
)}
75 %%% lame attempt of returning some more (lang. independent) detailed info...
76 analyse_string(Str
) ->
80 case substr(Str
, "too short") of
81 true
-> ?PWD_CHK_TOO_SHORT
;
82 _
-> is_dictionary(Str
)
86 case substr(Str
, "dictionary") of
87 true
-> ?PWD_CHK_DICTIONARY
;
92 case string:index(Str
, Sub
) of