screen-locker/scripts/workout_poke_keygen.sh
2026-10-09 19:05:51 +02:00

88 lines
2.1 KiB
Bash
Executable File

#!/bin/bash
# ============================================================================
# Create the phone -> PC workout poke key if it does not exist yet.
#
# The key is 32 random bytes as 64 hex characters in
# ~/.config/workout_poke/key (mode 600, dir 700). workout-poke.service verifies
# each poke's HMAC with it and refuses to start without it; pair_phone.sh
# copies it to the phone. An existing key is NEVER overwritten: a new key
# would silently unpair the phone. Prints the path, never the key.
#
# Usage: workout_poke_keygen.sh [--key-file PATH]
# ============================================================================
set -euo pipefail
KEY_FILE="${HOME}/.config/workout_poke/key"
readonly SCRIPT_NAME="${0##*/}"
readonly KEY_HEX_LENGTH=64
usage() {
echo "Usage: $SCRIPT_NAME [--key-file PATH]"
exit 0
}
# An existing key must still be well-formed and private, or the daemon will
# refuse it; say so here rather than let the unit fail later.
check_existing_key() {
local key mode
mode="$(stat -c '%a' "$KEY_FILE")"
if [[ $mode != "600" ]]; then
echo "Error: $KEY_FILE has mode $mode; run: chmod 600 $KEY_FILE" >&2
exit 1
fi
key="$(<"$KEY_FILE")"
if [[ ! $key =~ ^[0-9a-f]{$KEY_HEX_LENGTH}$ ]]; then
echo "Error: $KEY_FILE is not $KEY_HEX_LENGTH lowercase hex characters;" \
"move it aside and re-run (the phone must then be re-paired)" >&2
exit 1
fi
echo "Key already present: $KEY_FILE (left unchanged)"
}
create_key() {
local dir key
dir="$(dirname "$KEY_FILE")"
mkdir -p "$dir"
chmod 700 "$dir"
key="$(od -An -N32 -tx1 /dev/urandom | tr -d ' \n')"
if [[ ! $key =~ ^[0-9a-f]{$KEY_HEX_LENGTH}$ ]]; then
echo "Error: could not read 32 random bytes from /dev/urandom" >&2
exit 1
fi
# umask + noclobber: the file is born 600 and a racing creator loses.
(
umask 077
set -o noclobber
printf '%s\n' "$key" >"$KEY_FILE"
)
echo "Created key: $KEY_FILE (mode 600)"
}
main() {
if [[ -e $KEY_FILE ]]; then
check_existing_key
else
create_key
fi
}
while [[ $# -gt 0 ]]; do
case $1 in
--key-file)
KEY_FILE="$2"
shift 2
;;
-h | --help)
usage
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
main