-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhibp.bash
executable file
·105 lines (92 loc) · 2.61 KB
/
hibp.bash
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
#!/usr/bin/env bash
# pass hibp - Password Store Extension (https://www.passwordstore.org/)
# Copyright (C) 2017 Moviuro <[email protected]>.
cmd_hibp_usage() {
cat <<-_EOF
Usage:
$PROGRAM hibp [pass-name [...]]
Queries the haveibeenpwned HTTPS API to check if the passwords have been
compromised.
See https://haveibeenpwned.com/API/v2#PwnedPasswords
_EOF
exit 0
}
hibp_set_deps() {
if command -v sha1sum >/dev/null 2>&1; then
# GNU utils.
# outputs a needless ` -` at the end, thus grep(1)
hibp_sha() {
printf '%s' "$1" | sha1sum | grep -Eo '[a-f0-9]{40}'
}
elif command -v sha1 >/dev/null 2>&1; then
# BSD utils.
hibp_sha() {
printf '%s' "$1" | sha1
}
elif command -v openssl >/dev/null 2>&1; then
hibp_sha() {
printf '%s' "$1" | openssl sha1 | grep -Eo '[a-f0-9]{40}'
}
else
echo "No SHA1 utilities found :(" >&2
exit 1
fi
# The hibp_display_sha() function returns the hash prefix (5 char), then the
# hash suffix
hibp_display_sha() {
local _hash
_hash="$(hibp_sha "$1")"
printf '%s\n' "$_hash" | grep -Eo '^[a-f0-9]{5}'
printf '%s\n' "$_hash" | grep -Eo '[a-f0-9]{35}$'
}
# We append the hash prefix to the endpoint, and as a reply we either get a
# series of 'suffix: number' or a 404 HTTP error.
# In any case, we grep(1) for the suffix in the reply: if grep(1) fails, then
# the hash was not found; if grep(1) succeeds, then the hash was found and
# most probably the password was compromised
_endpoint=https://api.pwnedpasswords.com/range
if command -v curl >/dev/null 2>&1; then
hibp_query() {
mapfile -t _hashes < <(hibp_display_sha "$1")
curl -s "$_endpoint/${_hashes[0]}" | grep -oi "${_hashes[1]}" >/dev/null 2>&1
return $?
}
elif command -v fetch >/dev/null 2>&1; then
hibp_query() {
mapfile -t _hashes < <(hibp_display_sha "$1")
fetch -o - "$_endpoint/${_hashes[0]}" | grep -oi "${_hashes[1]}" >/dev/null 2>&1
return $?
}
else
echo "No downloading utilities found :(" >&2
exit 2
fi
}
hibp_test() {
local _path="$1"
local _password="$(pass show "${_path%%.gpg}" 2>/dev/null | head -n 1)"
if [[ -z "$_password" ]]; then
# Not testing empty passwords
return 0
elif hibp_query "$_password"; then
echo "$_path : compromised :(" >&2
fi
}
cmd_hibp() {
hibp_set_deps
case "$1" in
-h|--help) cmd_hibp_usage && exit 0 ;;
esac
local _path
if [[ -n "$1" ]]; then
for _path in "$@"; do
hibp_test "$_path"
done
else
cd "$PREFIX"
for _path in **/*\.gpg; do
hibp_test "$_path"
done
fi
}
cmd_hibp "$@"