mirror of
https://github.com/hassio-addons/bashio.git
synced 2025-05-03 10:31:25 +00:00
140 lines
4.4 KiB
Bash
140 lines
4.4 KiB
Bash
#!/usr/bin/env bash
|
|
# ==============================================================================
|
|
# Home Assistant Community Add-ons: Bashio
|
|
# Bashio is a bash function library for use with Home Assistant add-ons.
|
|
#
|
|
# It contains a set of commonly used operations and can be used
|
|
# to be included in add-on scripts to reduce code duplication across add-ons.
|
|
# ==============================================================================
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Checks if a given password is safe to use.
|
|
#
|
|
# Arguments:
|
|
# $1 The password to check
|
|
# ------------------------------------------------------------------------------
|
|
function bashio::pwned.is_safe_password() {
|
|
local password="${1}"
|
|
local occurrences
|
|
|
|
bashio::log.trace "${FUNCNAME[0]}" "<REDACTED PASSWORD>"
|
|
|
|
if ! occurrences=$(bashio::pwned "${password}"); then
|
|
bashio::log.warning "Could not check password, assuming it is safe."
|
|
return "${__BASHIO_EXIT_OK}"
|
|
fi
|
|
|
|
if [[ "${occurrences}" -ne 0 ]]; then
|
|
return "${__BASHIO_EXIT_NOK}"
|
|
fi
|
|
|
|
return "${__BASHIO_EXIT_OK}"
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Gets the number of occurrences of the password in the list.
|
|
#
|
|
# Arguments:
|
|
# $1 The password to check
|
|
# ------------------------------------------------------------------------------
|
|
function bashio::pwned.occurances() {
|
|
local password="${1}"
|
|
local occurrences
|
|
|
|
bashio::log.trace "${FUNCNAME[0]}" "<REDACTED PASSWORD>"
|
|
|
|
if ! occurrences=$(bashio::pwned "${password}"); then
|
|
occurrences="0"
|
|
fi
|
|
|
|
echo -n "${occurrences}"
|
|
return "${__BASHIO_EXIT_OK}"
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Makes a call to the Have I Been Pwned password database
|
|
#
|
|
# Arguments:
|
|
# $1 The password to check
|
|
# ------------------------------------------------------------------------------
|
|
function bashio::pwned() {
|
|
local password="${1}"
|
|
local response
|
|
local status
|
|
local hibp_hash
|
|
local count
|
|
|
|
bashio::log.trace "${FUNCNAME[0]}" "${password//./x}"
|
|
|
|
# Do not check empty password
|
|
if ! bashio::var.has_value "${password}"; then
|
|
bashio::log.warning 'Cannot check empty password against HaveIBeenPwned.'
|
|
return "${__BASHIO_EXIT_NOK}"
|
|
fi
|
|
|
|
# Hash the password
|
|
password=$(echo -n "${password}" \
|
|
| sha1sum \
|
|
| tr '[:lower:]' '[:upper:]' \
|
|
| awk -F' ' '{ print $1 }'
|
|
)
|
|
bashio::log.debug "Password SHA1: ${password}"
|
|
|
|
# Check with have I Been Pwned, only send the first 5 chars of the hash
|
|
if ! response=$(curl \
|
|
--silent \
|
|
--show-error \
|
|
--write-out '\n%{http_code}' \
|
|
--request GET \
|
|
"${__BASHIO_HIBP_ENDPOINT}/${password:0:5}"
|
|
); then
|
|
bashio::log.debug "${response}"
|
|
bashio::log.error "Something went wrong contacting the HIBP API"
|
|
return "${__BASHIO_EXIT_NOK}"
|
|
fi
|
|
|
|
status=${response##*$'\n'}
|
|
response=${response%"$status"}
|
|
|
|
bashio::log.debug "Requested API resource: ${__BASHIO_HIBP_ENDPOINT}/${password:0:5}"
|
|
bashio::log.debug "API HTTP Response code: ${status}"
|
|
bashio::log.trace "API Response: ${response}"
|
|
|
|
if [[ "${status}" -eq 429 ]]; then
|
|
bashio::log.error "HIBP Rate limit exceeded."
|
|
return "${__BASHIO_EXIT_NOK}"
|
|
fi
|
|
|
|
if [[ "${status}" -eq 503 ]]; then
|
|
bashio::log.error "HIBP Service unavailable."
|
|
return "${__BASHIO_EXIT_NOK}"
|
|
fi
|
|
|
|
if [[ "${status}" -ne 200 ]]; then
|
|
bashio::log.error "Unknown HIBP HTTP error occurred."
|
|
return "${__BASHIO_EXIT_NOK}"
|
|
fi
|
|
|
|
# Check the list of returned hashes for a match
|
|
for hibp_hash in ${response}; do
|
|
if [[ "${password:5:35}" == "${hibp_hash%%:*}" ]]; then
|
|
# Found a match! This is bad :(
|
|
count=$(echo "${hibp_hash#*:}" | tr -d '\r')
|
|
|
|
bashio::log.warning \
|
|
"Password is in the Have I Been Pwned database!"
|
|
bashio::log.warning \
|
|
"Password appeared ${count} times!"
|
|
echo "${count}"
|
|
|
|
# Well, at least the execution of this function succeeded.
|
|
return "${__BASHIO_EXIT_OK}"
|
|
fi
|
|
done
|
|
|
|
# Password was not found
|
|
echo "0"
|
|
bashio::log.info "Password is NOT in the Have I Been Pwned database! Nice!"
|
|
|
|
return "${__BASHIO_EXIT_OK}"
|
|
}
|