blob: bf4886f9783394832cd9af963d6680af62e54e25 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#!/bin/sh
#
# Copyright (c) 2017 by Stefan Esser <se@freebsd.org>
# All rights reserved.
#
# Distributed under the BSD 2-clause Simplified License.
#
CFGFILE="%%PREFIX%%/etc/pwned-check.conf"
[ -r "$CFGFILE" ] && . $CFGFILE
: ${DBDIR:=/var/db/pwned-check}
: ${URLBASE:=https://downloads.pwnedpasswords.com/passwords}
# Helper functions
progname ()
{
basename "$0"
}
errexit ()
{
echo $(progname)": $@"
exit 1
}
usage ()
{
echo "usage: "$(progname)" [-u]"
exit 2
}
# Fetch files with pwned password hashes
fetchpwfiles ()
{
umask 022
mkdir -p $DBDIR || errexit "No write permission on data directory."
local f s_txt s_txt_7z hash
while read f s_txt s_txt_7z hash
do
local f7z="$f.7z"
echo "Checking '$DBDIR/$f' ..."
local s_txt_is=$(stat -f %z $f 2>/dev/null)
if [ "$s_txt_is" != "$s_txt" ]; then
local s_txt_7z_is=$(stat -f %z $f7z 2>/dev/null)
if [ "$s_txt_7z_is" != "$s_txt_7z" ]; then
echo "Fetching '$DBDIR/$f7z' ..."
fetch -S $s_txt_7z "$URLBASE/$f7z" || errexit "Could not fetch '$URLBASE/$f7z'."
fi
echo "Checking '$DBDIR/$f7z' ..."
local hash_is=$(sha1 -q "$f7z")
if [ "$hash_is" != "$hash" ]; then
rm -f "$f7z"
errexit "File '$f7z' fails SHA1 check: '$hash_is' should be '$hash'."
fi
echo "Extracting '$DBDIR/$f' ..."
tar xOf "$f7z" | cut -d ":" -f 1 > "$f" || errexit "Decompression of file '$f7z' failed."
local s_txt_is=$(stat -f %z "$f")
if [ "$s_txt_is" != "$s_txt" ]; then
rm -f "$f"
errexit "File '$f' has size $s_txt_is after decompression, should be $s_txt."
fi
fi
rm -f "$f7z"
done <<EOF
pwned-passwords-ordered-2.0.txt 20567110522 9647404191 87437926c6293d034a259a2b86a2d077e7fd5a63
EOF
echo "All data files have been successfully downloaded and extracted."
# delete old data files (their content is included in the new datafiles)
while read f
do
rm -f $f $f.7z
done <<EOF
pwned-passwords-1.0.txt
pwned-passwords-update-1.txt
pwned-passwords-update-2.txt
EOF
}
# Password lookup
exitcode=0
lookup ()
{
local hash=$(echo "$1" | tr 'a-z' 'A-Z')
if [ "$USEFILES" = yes ]; then
look "$hash" pwned-passwords*.txt > /dev/null
else
expected=${hash#?????}
prefix=${hash%$expected}
fetch -q -o - https://api.pwnedpasswords.com/range/$prefix 2>/dev/null | grep -i "^$expected:" >/dev/null
fi
}
checkpw ()
{
local pwd="$1"
local hash=$(echo -n "$pwd" | sha1)
if lookup "$hash"; then
echo "$pwd"
exitcode=1
elif expr "$pwd" : '[A-Fa-f0-9]\{40\}$' > /dev/null; then
if lookup "$pwd"; then
echo "$pwd"
exitcode=1
fi
fi
}
# Main program
export LC_COLLATE=C
if cd "$DBDIR" && ls pwned-passwords*.txt; then
USEFILES=yes
fi >/dev/null 2>&1
if [ "$#" -gt 0 ]; then
if [ "$1" = "-u" ]; then
fetchpwfiles
exit 0
else
echo "usage: "$(progname)" [-u]"
exit 2
fi
fi
while read pwd
do
checkpw "$pwd"
done
exit $exitcode
|