blob: c2db91269d80d9a0423e5753ec3b198b8ece8e55 [file] [log] [blame] [raw]
# Copyright 2015-2024 Rivoreo
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
# IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
_load_encryped_history_internal() {
[ -n "$HISTORY_KEY" ] || return
local tmp_history_file r=1
tmp_history_file="`mktemp \"$HOME/.bash_history.$$.XXXXXX\"`" || return
if _decrypt_history "$HISTORY_KEY" < "$ENCRYPTED_HISTORY_FILE" > "$tmp_history_file"; then
history -r "$tmp_history_file" && r=0
fi
rm -f "$tmp_history_file"
return $r
}
load_encryped_history() {
[ "${-#*i}" = "$-" ] && return 1
[ -f "$ENCRYPTED_HISTORY_FILE" ] || return
begin_print_status "Loading history"
if _load_encryped_history_internal; then
end_print_status_ok
else
end_print_status_fail
fi
}
_append_encrypted_history_internal() {
[ -n "$HISTORY_KEY" ] || return
local value nonce pad
if get_encrypted_byte_count "$ENCRYPTED_HISTORY_FILE"; then
nonce=$((value/8))
pad=$((value%8))
else
nonce=0
pad=0
chmod 600 "$ENCRYPTED_HISTORY_FILE" >> "$ENCRYPTED_HISTORY_FILE" || return
fi
if [ "$1" = -e ]; then
history -a /dev/stdout | _encrypt_history "$HISTORY_KEY" $nonce $pad >> "$ENCRYPTED_HISTORY_FILE"
return
fi
local history_pipe="$HOME/.bash_history.$$" pid r=0
rm -f "$history_pipe"
mkfifo -m 600 "$history_pipe" || return
_encrypt_history "$HISTORY_KEY" $nonce $pad < "$history_pipe" >> "$ENCRYPTED_HISTORY_FILE" & pid=$!
history -a "$history_pipe" || r=1
wait $pid || r=1
rm -f "$history_pipe"
return $r
}
append_encrypted_history() {
[ "${-#*i}" = "$-" ] && return 1
begin_print_status "Storing history"
if _append_encrypted_history_internal "$@"; then
end_print_status_ok
else
end_print_status_fail
fi
}
ask_history_passphrase() {
local passphrase
read -rs -p "History key or passphrase? " passphrase && [ -n "$passphrase" ] || return
echo 1>&2
if printf %s\\n "$passphrase" | grep -Eq '^[0-9a-f]{32}$'; then
HISTORY_KEY="$passphrase"
elif HISTORY_KEY="`printf %s \"$passphrase\" | md5sum 2> /dev/null`"; then
HISTORY_KEY="${HISTORY_KEY%% *}"
elif HISTORY_KEY="`md5 -q -s \"$passphrase\" 2> /dev/null`"; then
true
elif HISTORY_KEY="`printf %s \"$passphrase\" | toolbox md5 -q -- - 2> /dev/null`"; then
true
else
echo "Couldn't find a working md5sum(1) or md5(1) tool" 1>&2
false
fi
}
if [ "${-#*i}" != "$-" ]; then
for f in "$HOME"/.bash_history.*.??????; do
if [ -h "$f" ]; then
rm -f "$f"
continue
fi
[ -e "$f" ] || continue
if [ ! -f "$f" ]; then
printf "Warning: Found non-regular file '%s'\\n" "${f##*/}" 1>&2
continue
fi
pid="${f##*/.bash_history.}"
pid="${pid%.??????}"
if printf %s\\n "$pid" | grep -Eq '^[0-9]+$'; then
[ -d "/proc/$pid" ] || ps -p "$pid" > /dev/null && continue
fi
rm -f "$f" > "$f"
done
unset HISTFILE
if [ -n "${HISTORY_KEY+set}" ]; then
if printf %s\\n "$HISTORY_KEY" | grep -Eq '^[0-9a-fA-F]{32}$'; then
# Unexport this variable for security
declare +x HISTORY_KEY
else
echo "Warning: Predefined HISTORY_KEY is invalid" 1>&2
unset HISTORY_KEY
fi
fi
if [ -n "$HISTORY_KEY" ] || ask_history_passphrase; then
[ -z "$ENCRYPTED_HISTORY_FILE" ] && ENCRYPTED_HISTORY_FILE="$HOME/.bash_history.e"
load_encryped_history
trap "append_encrypted_history -e" EXIT
else
echo "Warning: Persistent history disabled" 1>&2
HISTORY_KEY=
fi
fi