]> eyrie.org Git - kerberos/krb5-strength.git/blob - tools/cdbmake-wordlist
Change my email address to eagle@eyrie.org
[kerberos/krb5-strength.git] / tools / cdbmake-wordlist
1 #!/usr/bin/perl
2 #
3 # Turn a wordlist into a cdb file.
4 #
5 # cdb is a format invented by Dan Bernstein for fast, constant databases.  The
6 # database is fixed during creation and cannot be changed without rebuilding
7 # it, and is optimized for very fast access.  This program takes as input a
8 # wordlist file (a set of words separated by newlines) and turns it into a cdb
9 # file with the words as keys and the constant "1" as a value.  The resulting
10 # database is suitable for fast existence lookups in the wordlist, such as for
11 # password dictionary checks.
12
13 require 5.006;
14 use strict;
15 use warnings;
16
17 use File::Basename qw(basename);
18 use Getopt::Long qw(GetOptions);
19
20 # The path to the cdb utility, used to create the final database.  By default,
21 # the user's PATH is searched for cdb.
22 my $CDB = 'cdb';
23
24 # print with error checking and an explicit file handle.
25 #
26 # $fh   - Output file handle
27 # @args - Remaining arguments to print
28 #
29 # Returns: undef
30 #  Throws: Text exception on output failure
31 sub print_fh {
32     my ($fh, @args) = @_;
33     print {$fh} @args or croak('print failed');
34     return;
35 }
36
37 # Always flush output.
38 STDOUT->autoflush;
39
40 # Clean up the script name for error reporting.
41 my $fullpath = $0;
42 local $0 = basename($0);
43
44 # Parse the argument list.
45 my ($ascii, $min_length, $manual);
46 Getopt::Long::config('bundling', 'no_ignore_case');
47 GetOptions(
48     'ascii|a'        => \$ascii,
49     'min-length|l=i' => \$min_length,
50     'manual|man|m'   => \$manual
51 );
52 if ($manual) {
53     print_fh(\*STDOUT, "Feeding myself to perldoc, please wait...\n");
54     exec('perldoc', '-t', $fullpath);
55 }
56 if (@ARGV != 1) {
57     die "Usage: cdbmake-wordlist <wordlist>\n";
58 }
59 my $input = $ARGV[0];
60
61 # The output file goes in the same directory and is named the same as the
62 # input but with .data appended.
63 my $output = $input . '.data';
64 if (-f $output) {
65     die "$0: temporary output file $output already exists\n";
66 }
67
68 # Process the input file into the output file, converting it to cdb input
69 # format.
70 open(my $in, '<', $input)
71   or die "$0: cannot open input file $input: $!\n";
72 open(my $out, '>', $output)
73   or die "$0: cannot create output file $output: $!\n";
74 while (defined(my $word = <$in>)) {
75     chomp($word);
76     my $length = length($word);
77     next if (defined($min_length) && $length < $min_length);
78     if ($ascii) {
79         next if $word =~ m{ [^[:ascii:]] }xms;
80         next if $word =~ m{ [[:cntrl:]] }xms;
81     }
82     print_fh($out, "+$length,1:$word->1\n");
83 }
84 print_fh($out, "\n");
85 close($in)  or die "$0: cannot read all of input file $input: $!\n";
86 close($out) or die "$0: cannot write to output file $output: $!\n";
87
88 # Run cdb to turn the result into a constant database.  Ignore duplicate keys.
89 system($CDB, '-c', '-u', "$input.cdb", $output) == 0
90   or die "$0: cdb -c failed\n";
91
92 # Remove the temporary file.
93 unlink($output) or die "$0: cannot remove temporary file $output: $!\n";
94
95 # All done.
96 exit(0);
97 __END__
98
99 =for stopwords
100 cdbmake-wordlist cdb whitespace wordlist lookups lookup sublicense
101 MERCHANTABILITY NONINFRINGEMENT krb5-strength --ascii Allbery
102
103 =head1 NAME
104
105 cdbmake-wordlist - Create a cdb database from a wordlist
106
107 =head1 SYNOPSIS
108
109 B<cdbmake-wordlist> [B<-am>] [B<-l> I<length>] I<wordlist>
110
111 =head1 DESCRIPTION
112
113 cdb is a format invented by Dan Bernstein for fast, constant databases.
114 The database is fixed during creation and cannot be changed without
115 rebuilding it, and is optimized for very fast access.  This program takes
116 as input a wordlist file (a set of words, possibly including whitespace,
117 separated by newlines) and turns it into a cdb file with the words as keys
118 and the constant C<1> as a value.  The resulting database is suitable for
119 fast existence lookups in the wordlist, such as for password dictionary
120 checks.
121
122 B<cdbmake-wordlist> takes one argument, the input wordlist file.  The
123 output cdb database will have the same name as I<wordlist> but with
124 C<.cdb> appended.  The input wordlist file does not have to be sorted.
125
126 =head1 OPTIONS
127
128 =over 4
129
130 =item B<-a>, B<--ascii>
131
132 Filter all words that contain non-ASCII characters or control characters
133 from the resulting cdb file, leaving only words that consist solely of
134 ASCII non-control characters.
135
136 =item B<-l> I<minimum>, B<--min-length>=I<minimum>
137
138 Filter all words of length less than I<minimum> from the resulting cdb
139 database.  The length of each line (minus the separating newline) in the
140 input wordlist will be checked against I<minimum> and will be filtered out
141 of the resulting database if it is shorter.  Useful for generating password
142 dictionaries where shorter passwords will be rejected by a generic length
143 check and no dictionary lookup will be done for a transform of the password
144 shorter than the specified minimum.
145
146 The default is not to filter out any words for minimum length.
147
148 =item B<-m>, B<--man>, B<--manual>
149
150 Print out this documentation (which is done simply by feeding the script to
151 C<perldoc -t>).
152
153 =back
154
155 =head1 AUTHOR
156
157 Russ Allbery <eagle@eyrie.org>
158
159 =head1 COPYRIGHT AND LICENSE
160
161 Copyright 2013 The Board of Trustees of the Leland Stanford Junior
162 University
163
164 Permission is hereby granted, free of charge, to any person obtaining a
165 copy of this software and associated documentation files (the "Software"),
166 to deal in the Software without restriction, including without limitation
167 the rights to use, copy, modify, merge, publish, distribute, sublicense,
168 and/or sell copies of the Software, and to permit persons to whom the
169 Software is furnished to do so, subject to the following conditions:
170
171 The above copyright notice and this permission notice shall be included in
172 all copies or substantial portions of the Software.
173
174 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
175 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
176 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
177 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
178 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
179 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
180 DEALINGS IN THE SOFTWARE.
181
182 =head1 SEE ALSO
183
184 cdb(1)
185
186 The cdb file format is defined at L<http://cr.yp.to/cdb.html>.
187
188 The current version of this program is available from its web page at
189 L<http://www.eyrie.org/~eagle/software/krb5-strength/> as part of the
190 krb5-strength package.
191
192 =cut