Files
ubuntu-based-kiosk/menus/hidden_pin.sh
T
Claude d6769d5207 Hash the hidden-sites PIN and slow down repeated wrong PINs
.jitsi-pin now holds "sha256:<hex>" (or NOPIN) instead of the digits.
The menu writes the hashed form. A plain-digits file still works and
is converted by the kiosk app at startup.

The PIN is now checked in the main process instead of the PIN pad's
renderer, using the lock screen's slowdown, now factored out
(createCodeThrottle): 5 wrong in a row refuse entry for 30s, doubling
up to 5 minutes. The F10 PIN pad and the WiFi screen share one count.
The WiFi screen's close-after-5-tries is replaced by this. The PIN pad
no longer shows the default PIN on screen, and the menu no longer
echoes the PIN as it's typed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cjz8a58eB5P9sUweqd3NHm
2026-10-10 15:33:05 +00:00

104 lines
3.2 KiB
Bash

#!/bin/bash
################################################################################
# menus/hidden_pin.sh - "Hidden Site PIN" menu.
#
# Guards access to hidden pages (duration = -1, see menus/sites.sh) via a
# flat PIN file rather than config.json - a fourth shape for the framework
# to prove out (plain file, not JSON at all).
#
# The file holds "NOPIN", or "sha256:<hex>" - the PIN is never stored as
# plain digits (a file from before that is converted by the kiosk app at
# startup; plain digits are still accepted until then). No file = the
# default PIN 1234. The kiosk app reads it on every check, so changes
# apply immediately, and slows down repeated wrong guesses.
#
# Depends on: lib/menu.sh, lib/config.sh being sourced first.
################################################################################
hidden_pin_file() {
echo "$KIOSK_DIR/.jitsi-pin"
}
hidden_pin_status() {
local pin_file
pin_file=$(hidden_pin_file)
if sudo -u "$KIOSK_USER" test -f "$pin_file" 2>/dev/null; then
local current_pin
current_pin=$(sudo -u "$KIOSK_USER" cat "$pin_file" 2>/dev/null)
if [[ "$current_pin" == "NOPIN" ]]; then
echo "Current: no PIN (hidden pages open to anyone)"
elif [[ "$current_pin" == "sha256:$(hidden_pin_hash 1234)" || "$current_pin" == "1234" ]]; then
echo "Current: default PIN (1234) - set your own"
else
echo "Current: PIN set"
fi
else
echo "Current: not configured (default: 1234)"
fi
}
hidden_pin_menu_builder() {
MENU_LABELS=("Set new PIN (4-8 digits)" "Disable PIN (open access)" "Reset to default (1234)")
MENU_HANDLERS=(action_set_pin action_disable_pin action_reset_pin)
}
hidden_pin_menu() {
run_menu "HIDDEN SITE PIN" hidden_pin_menu_builder hidden_pin_status
}
################################################################################
# Actions
################################################################################
hidden_pin_hash() {
echo -n "$1" | sha256sum | cut -d' ' -f1
}
# write_pin VALUE - VALUE is "NOPIN" or the PIN digits (stored hashed).
write_pin() {
local value="$1"
local pin_file
pin_file=$(hidden_pin_file)
[[ "$value" == "NOPIN" ]] || value="sha256:$(hidden_pin_hash "$value")"
sudo mkdir -p "$KIOSK_DIR"
echo "$value" | sudo -u "$KIOSK_USER" tee "$pin_file" > /dev/null
sudo -u "$KIOSK_USER" chmod 600 "$pin_file"
}
action_set_pin() {
echo
local new_pin confirm_pin
while true; do
read -r -s -p "Enter new PIN (4-8 digits): " new_pin
echo
if [[ ! "$new_pin" =~ ^[0-9]{4,8}$ ]]; then
echo "❌ PIN must be 4-8 digits"
continue
fi
read -r -s -p "Confirm PIN: " confirm_pin
echo
if [[ "$new_pin" == "$confirm_pin" ]]; then
write_pin "$new_pin"
log_success "PIN updated"
break
else
echo "❌ PINs don't match, try again"
fi
done
}
action_disable_pin() {
write_pin "NOPIN"
log_success "PIN disabled - hidden pages accessible without a PIN"
}
action_reset_pin() {
write_pin "1234"
log_success "PIN reset to default (1234)"
}