#!/bin/sh # # Copyright (c) 2017 by Stefan Esser # 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 < /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