diff options
author | Ben Burwell <ben@benburwell.com> | 2018-02-23 23:00:12 -0500 |
---|---|---|
committer | Ben Burwell <ben@benburwell.com> | 2018-02-23 23:00:12 -0500 |
commit | 6ec8b3e334dd35dd8c7a168d3a182a5bd3289c9f (patch) | |
tree | 4344455bcc7a3ef26340089690c8804c9af6eb77 |
Initial commit
-rwxr-xr-x | audit.bash | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/audit.bash b/audit.bash new file mode 100755 index 0000000..b7de93e --- /dev/null +++ b/audit.bash @@ -0,0 +1,108 @@ +#!/usr/bin/env bash + +pwned_hibp () { + local sha=$(echo "$1" | tr -d '\n' | shasum | cut -c 1-40 | tr '[:lower:]' '[:upper:]') + local prefix=$(echo "$sha" | cut -c 1-5) + local suffix=$(echo "$sha" | cut -c 6-40) + if [[ $(curl --silent "https://api.pwnedpasswords.com/range/$prefix" | grep "$suffix") ]]; then + return 1 + fi + return 0 +} + +pwned_wordlist () { + local wordlist="$1" + local password="$2" + if [[ ! -f "$wordlist" ]]; then + die "Wordlist not found" + fi + if [[ $(echo "$password" | grep --file="$wordlist") ]]; then + return 1 + fi + return 0 +} + +cmd_audit_password () { + local opts wordlist use_wordlist=0 use_hibp=0 + opts="$($GETOPT -o w:p -l wordlist:,hibp -n "$PROGRAM" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + -w|--wordlist) use_wordlist=1; wordlist="${2:-1}"; shift 2 ;; + -h|--hibp) use_hibp=1; shift ;; + --) shift; break ;; + esac done + + local path="${1%/}" + local passfile="$PREFIX/$path.gpg" + check_sneaky_paths "$path" + [[ -f $passfile ]] || die "Passfile not found" + + [[ $use_wordlist -eq 1 ]] || [[ $use_hibp -eq 1 ]] || die "Please use either --hibp or --wordlist" + + local password=$($GPG -d "${GPG_OPTS[@]}" "$passfile" | head -n 1 | tr -d '\n') + + local pwned=0 + + if [[ $use_hibp -eq 1 ]]; then + pwned_hibp "$password" + if [[ $? -eq 1 ]]; then + pwned=1 + fi + fi + + if [[ $use_wordlist -eq 1 ]]; then + pwned_wordlist "$wordlist" "$password" + if [[ $? -eq 1 ]]; then + pwned=1 + fi + fi + + if [[ $pwned -eq 1 ]]; then + echo "$path" + return 1 + fi + return 0 +} + + +cmd_audit_all_passwords () { + local prefix_len=$(echo "$PREFIX" | wc -c | tr -d ' ') + local pwned=0 + for p in $(find "$PREFIX" -name "*.gpg"); do + path=$(echo "$p" | cut -c "$prefix_len-" | cut -c 2- | sed 's/.gpg$//') + cmd_audit_password "$@" "$path" + if [[ $? -ne 0 ]]; then + pwned=1 + fi + done + return $pwned +} + +cmd_audit_usage () { + cat <<-_EOF +Usage: + + $PROGRAM audit [--hibp,-p] [--wordlist,-w list-file] pass-name + Check whether a password has been pwned, either by consulting Have I + Been Pwned or a wordlist file (or both). You can specify either or + both options, but without at least one, nothing will happen. + + $PROGRAM audit all [--hibp,-p] [--wordlist,-w list-file] + Check all the passwords in your store against Have I Been Pwned and/or + the provided wordlist. + +More information is available from the pass-audit(1) man page. +_EOF + exit 0 +} + +case "$1" in + help|--help|-h) shift; cmd_audit_usage "$@" ;; + --all) shift; cmd_audit_all_passwords "$@" ;; + *) cmd_audit_password "$@" ;; +esac + +exit $? + +# vim: :set shiftwidth=2 expandtab: |